ncat echo server, write incoming message to shell? - linux

Is there a way to get ncat to print what it receives to the terminal before it echos back on the port with cat, Looks like the executed code doesn't have access to stdio?
I think tee is supposed copy stdout to cat with something like this, but I don't see any output.
ncat -e '/usr/bin/tee > (/bin/cat)' -l -p 2048

Related

How to make a "same response" server with bash?

I'm trying to set up a simple server that returns always the same response.
Based on this question I've tried to use
ncat -l 2000 --keep-open --exec "/bin/echo 234"
but on the client it shows only once.
Ncat: Broken pipe.
If I use the UDP option (-u), it works as intended. So I'm guessing it's EOF's fault.
Is there a way to make it work as a reponse to the client's messages in TCP?
For something as simple you could:
ncat -l 2000 --keep-open --exec "xargs -I{} echo 234"
I find also the following works:
ncat -l 2000 --keep-open --sh-exec "while read line; do echo 234; done"
or like:
ncat -l 2000 --keep-open --sh-exec "echo 234; cat >/dev/null"

Redirect new xterm's output back to the original terminal

For example, I have a very simple script, ping.sh:
#!/bin/bash
/usr/bin/xterm -e ping localhost
Right now, the output of the ping only shows up in the new xterm. I would like the output to show in both the original terminal (stdout of ping.sh) as well as in the new xterm. Is there a way to do this?
PS: I'm struggling with a title for this.
Seems like a weird thing to do, but this might work:
#!/bin/bash
f=$(mktemp)
touch "$f"
tail -f "$f" &
/usr/bin/xterm -e "sh -c 'ping localhost 2>&1 | tee -a $f'"
Alternatively, it's possible to get the file name of the terminal connected to standard input using the command tty, then use tee in the new terminal to copy the output to the old terminal.
/usr/bin/xterm -e "ping localhost | tee $(tty)"
Of course, this only works if the script is not called with redirected stdin.
In case the script is called with redirected stdin, solutions in shell - How to get the real name of the controlling terminal? - Unix & Linux Stack Exchange can be used. readlink /proc/self/fd/1, or ps (require some output parsing)

What is meant by 'output to stdout'

New to bash programming. I am not sure what is meant by 'output to stdout'. Does it mean print out to the command line?
If I have a simple bash script:
#!/bin/bash
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello'
it outputs a string to the terminal. Does this mean it's 'outputting to stdout' ?
Thanks
Yes, stdout is the terminal (unless it's redirected to a file using the > operator or into the stdin of another process using |)
In your specific example, you're actually redirecting using | grep ... through grep then to the terminal.
Every process on a Linux system (and most others) has at least 3 open file descriptors:
stdin (0)
stdout (1)
stderr (2)
Regualary every of this file descriptors will point to the terminal from where the process was started. Like this:
cat file.txt # all file descriptors are pointing to the terminal where you type the command
However, bash allows to modify this behaviour using input / output redirection:
cat < file.txt # will use file.txt as stdin
cat file.txt > output.txt # redirects stdout to a file (will not appear on terminal anymore)
cat file.txt 2> /dev/null # redirects stderr to /dev/null (will not appear on terminal anymore
The same is happening when you are using the pipe symbol like:
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello'
What is actually happening is that the stdout of the wget process (the process before the | ) is redirected to the stdin of the grep process. So wget's stdout isn't a terminal anymore while grep's output is the current terminal. If you want to redirect grep's output to a file for example, then use this:
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello' > output.txt
Unless redirected, standard output is the text terminal which initiated the program.
Here's a wikipedia article: http://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29

Using named pipes to create a 'loop'

I'm very new to shell scripting and I am trying to get to grips with piping. I could be heading in completely the wrong direction here...
What I have is a shell script that contains a simple while true loop, within this loop I am getting netcat to listen on a specified port and piping input to a binary file that is awaiting for commands through stdin. This is Script-A
I have a second shell script that accepts input as arguments, it then echos those arguments to the port that netcat is listening on. This is Script-B
My aim is to get the returning output from the binary file located in Script-A into Script-B via Netcat so that it can be returned via stdout. The binary file has to be initialized and awaiting input.
This is what I have:
Script-A
while true; do
nc -kl 1234 | /binarylocation/ --readargumentsfromstdinflag
done
Script-B
foo=$(echo "$*" | nc localhost 1234)
echo "$foo"
With this setup, the output of the binary file is done via Script-A
After doing some research I got to this point, I am trying to use a named pipe to create a sort of loop from the binary file back to netcat, it's still not working -
Script-A
mkfifo foobar
while true; do
nc -kl 1234 < foobar | /binarylocation/ --readargumentsfromstdinflag > foobar
done
Script-B hasn't changed.
Bear in mind my shell scripting experience stems over a period of about a single day, thank you.
The problem is in your script B.. netcat reads from STDIN and exits immediately when STDIN is closed, not waiting for the response.
you will realize when you do this:
foo=$( ( echo -e "$*"; sleep 2 ) | nc localhost 1234)
echo "$foo"
nc has a parameter for the stdin behaviour..
-q after EOF on stdin, wait the specified number of seconds and
then quit. If seconds is negative, wait forever.`
So you should do:
foo=$( echo -e "$*" | nc -q5 localhost 1234)
echo "$foo"

How to log output in bash and see it in the terminal at the same time?

I have some scripts where I need to see the output and log the result to a file, with the simplest example being:
$ update-client > my.log
I want to be able to see the output of the command while it's running, but also have it logged to the file. I also log stderr, so I would want to be able to log the error stream while seeing it as well.
update-client 2>&1 | tee my.log
2>&1 redirects standard error to standard output, and tee sends its standard input to standard output and the file.
Just use tail to watch the file as it's updated. Background your original process by adding & after your above command After you execute the command above just use
$ tail -f my.log
It will continuously update. (note it won't tell you when the file has finished running so you can output something to the log to tell you it finished. Ctrl-c to exit tail)
You can use the tee command for that:
command | tee /path/to/logfile
The equivelent without writing to the shell would be:
command > /path/to/logfile
If you want to append (>>) and show the output in the shell, use the -a option:
command | tee -a /path/to/logfile
Please note that the pipe will catch stdout only, errors to stderr are not processed by the pipe with tee. If you want to log errors (from stderr), use:
command 2>&1 | tee /path/to/logfile
This means: run command and redirect the stderr stream (2) to stdout (1). That will be passed to the pipe with the tee application.
Learn about this at askubuntu site
another option is to use block based output capture from within the script (not sure if that is the correct technical term).
Example
#!/bin/bash
{
echo "I will be sent to screen and file"
ls ~
} 2>&1 | tee -a /tmp/logfile.log
echo "I will be sent to just terminal"
I like to have more control and flexibility - so I prefer this way.

Resources