Why does >/dev/null not work as expected? - bash

I have written the following shell script:
#! /bin/bash
# This script is designed to find hosts with MySQL installed
nmap -sT my_IP_address -p 3306 >/dev/null -oG MySQLscan
cat MySQLscan | grep open > MySQLscan2
cat MySQLscan2
According to the script the output of nmap should be sent to /dev/null. On the other hand, the final out put should be written to the file MySQLscan2 in my pwd.
Not as I have expected, two files are written to my pwd:
MySQLscan: Contains the output of the scan that I have expected to be in MySQLscan2.
MySQLscan2: This file is empty.
Is there an mistake in my script? How can I solve the problem?
Earlier today, I managed to run the script with correct output. I am not sure if I have changed the script in some way. I checked it again and again, but cannot find, what is wrong...
I am working with Kali Linux and Oracle VM Virtual Box.

> /dev/null causes shell to redirect stdout, that is a file with
file descriptor to 1
to /dev/null before the command starts so in other words to discard
it. When nmap runs with -oG MySQLscan option it opens a new file and
gets a new file descriptor. You can check it with strace:
$ strace -f nmap -sT localhost -p 3306 -oG MySQLscan |& grep MySQLscan
execve("/usr/bin/nmap", ["nmap", "-sT", "localhost", "-p", "22", "-oG", "MySQLscan"], 0x7ffc88805198 /* 60 vars */) = 0
openat(AT_FDCWD, "MySQLscan", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
In this example openat() returned 4 as a new file descriptor (you
can read more about this function with man 2 openat). Since file
descriptor 4 hasn't been redirected before command started MySQLscan
gets created. Also notice that even if file descriptor that openat()
returns to open MySQLscan is redirected to /dev/null:
nmap -sT localhost -p 22 -oG MySQLscan 4>/dev/null
it doesn't prevent MySQLscan from being created because openat()
requests a new unused file descriptor from kernel every time it's
run.

Related

How to make the ssh with -o StrictHostKeyChecking=no running on the docker in order to ssh the host work without exiting the script execution?

I have a script, that is running inside the docker container some actions we need for some internal debugging purposes:
set -eu
echo "Starting i/o test for host"
IP_HOST=$(ip a | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | grep 172.17 | awk 'NR==1{print $1}')
echo "Detected IP of host is $IP_HOST"
sshpass -p tcuser ssh -o StrictHostKeyChecking=no docker#localhost -t -t
echo "Then"
the output here produce exactly:
bash-5.0# sh /etc/cron.d/iotesthost.sh
Mon Mar 2 12:43:59 UTC 2020
Starting i/o test for host
Detected IP of host is 172.17.0.1
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
( '>')
/) TC (\ Core is distributed with ABSOLUTELY NO WARRANTY.
(/-_--_-\) www.tinycorelinux.net
and as the last line is reached, the script makes me exiting bash or crond execution. So I can't go ahead with processing other lines after sshpass/ssh, so I never reach echo "Then"
That is the reason of exiting the script execution and how to work it around, still keeping all the features of accepting keys (i need is as each time the docker container calls for the script it is new)
If I ignore -t -t, I'm getting error according to https://stackoverflow.com/a/7122115/1759063
see https://askubuntu.com/questions/87449/how-to-disable-strict-host-key-checking-in-ssh
or
echo "StrictHostKeyChecking no" >> /etc/ssh_config
for a global solution. Please note that there is no security check anymore then.

tcpdump suppress console output in script & write to file

In a bash script I need to run a tcpdump command and save the output to a file however when I do that via > /tmp/test.txt i still get the following output in the console:
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 1500 bytes
1 packet captured
1 packet received by filter
0 packets dropped by kernel
However I do wnat the script to wait for the command to complete before continuing.
is it possible to supress this output?
The output you're seeing is written to stderr, not stdout, so you can redirect it to /dev/null if you don't want to see it. For example:
tcpdump -nn -v -i eth0 -s 1500 -c 1 'ether proto 0x88cc' > /tmp/test.txt 2> /dev/null

Tcpdump with -w writing gibberish to file

When trying to capture tcpdump output to a file, I get the following:
▒ò▒▒▒▒3▒X▒▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒Xu<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒D<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒D<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X5▒<<▒▒▒▒▒▒▒4▒4▒b
7
7▒▒3▒X▒<<▒▒▒▒▒▒▒4▒4▒b
If I run tcpdump without the -w the output displays fine in the shell.
Here is the input:
tcpdump -i eth0 -Z root -w `date '+%m-%d-%y.%T.pcap'`
tcpdump -w writes the raw file, which is not meant for reading directly. You can read the file back with the tcpdump -r option as suggested in the man page:
-r Read packets from file (which was created with the -w option). Standard input is used if file is ‘‘-’’.
-w Write the raw packets to file rather than parsing and printing them out. They can later be printed with the -r option. Standard output is used if file is ‘‘-’’. See pcap-savefile(5) for a description of the file format.
Another option would be to redirect the output without using the -w option:
tcpdump -i eth0 -Z root > `date '+%m-%d-%y.%T.pcap'`
But if I remember correctly you don’t get exactly what would be written with the -w option.

socat - problems with logfile to tcp binding

I have a question to using socat in a special situation. I have a logfile on a system e.g. /var/log/logfile.log and I want to do a binding from the logfile to a tcp (telnet) connection.
So when I start a telnet to the system I will see new entries in the logfile.
I try this:
sudo socat -v tcp-l:4712,reuseaddr,fork file:"/var/lser2net/ser2net.log",nonblock,
That works but even when a new entry will write in the logfile, I got the whole logfile via telnet again.
I only need new lines, not the whole logfile.
Any ideas?
Using the tail command:
To see the last 10 lines and then all new ones until the connection is closed:
socat -v tcp-l:4712,reuseaddr,fork exec:"tail -f -n10 /var/lser2net/ser2net.log"
To see only the last 10 lines:
socat -v tcp-l:4712,reuseaddr,fork exec:"tail -n10 /var/lser2net/ser2net.log"
To see only new lines until the connection is closed:
socat -v tcp-l:4712,reuseaddr,fork exec:"tail -f -n0 /var/lser2net/ser2net.log"
Good luck!

ssh login without welcome banner

I am using ssh from a program which sends commands to ssh and parses answers. However, each time I log in, I get the welcome banner like:
Linux mymachine 3.2.0-4-686-pae #1 SMP Debian 3.2.54-2 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
...
I do not want this banner, because my parser would need to deal with it. Is it possible to login with ssh and not to get this banner at the beginning?
You should be able to silence this banner, and other diagnostic messages, by passing -q to SSH:
ssh -q user#remote_host
If you want to make -q permanent for all your SSH sessions, do:
echo "LogLevel QUIET" >> ~/.ssh/config
What works here seems to depend on the operating system, SSH version, and the server-side configuration of sshd.
For connecting to a stock Ubuntu 18 server ssh -q didn't work for me, and neither did ssh -o LogLevel=error that is suggested elsewhere.
What did work is the comment posted under the question about creating a .hushlogin file in the remote user's home directory:
$ ssh myuser#myhost
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-55-generic x86_64)
<snip>
Last login: Thu Aug 1 14:04:26 2019 from 1.2.3.4
myuser#myhost$ touch .hushlogin
myuser#myhost$ exit
Then:
$ ssh myuser#myhost echo 'Test'
Test
This will run command1 command2 and command3 on the remote_host.
ssh user#remote_host 'command1; command2; command3'
No banners are displayed.
Try ssh -q to supress the banner message
If you expect more than 1000 lines in the server answer then replace 1000 with a corresponding number or the server answer will be truncated.
# Demo script file creation \
DIVIDER="___"; echo "echo $DIVIDER; echo 100; echo 200; echo 300;" > "./test.sh"; \
# \
# Getting the answer without the banner \
ssh -q login#server.name < "./test.sh" | grep -A1000 -e "^$DIVIDER" | tail -n +2
Success
100
200
300
The same command without
| grep -A1000 -e "^$DIVIDER" | tail -n +2
gives
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux...
[...]
Run 'do-release-upgrade' to upgrade to it.
___
100
200
300
You can replace "___" (three underscores) with any exotic sign(s) or even password (which can't be found in the beginnings of lines of the banner).
To avoid the replacing 1000 with a corresponding number (and possible truncation of big server answers) search something about "how to grep all lines after match" and modify my code.
For running commands remotely:
#!/bin/bash
SCRIPT='
#Your commands
'
sshpass -p<pass> ssh -o 'StrictHostKeyChecking no' -p <port> user#host "$SCRIPT"
I answer my own question with the solution based on Keith Reynolds answer. I am using:
ssh my_host bash
allowing bash interaction without banner and without prompt.

Resources