I have composed the following script:
sudo tcpdump -vv -n -s 0 -k NP | grep xx.xxx.xx.xx | until [[ '! xx.xxx.xx.xx' ]] do sleep 1 done killall -9 'Pages',
where xx.xxx.xx.xx is a particular IP address, and where sudo tcpdump -vv -n -s 0 -k NP, obviously, continuously checks for active connections, and | grep xx.xxx.xx.xx filters out the xx.xxx.xx.xx IP address out of all the active connections tcpdump finds.
This filtered out IP address is then piped on to the until statement, where:
| until [[ '! xx.xxx.xx.xx' ]] do sleep 1 done
is supposed to check when there is no connection with the xx.xxx.xx.xx IP address. If such a connection exists, the until statement is supposed to sleep for one second only, and continue checking. If, on the contrary, such a connection does not exists, the until statement is supposed to pass on to the killall command, which, for the sake of testing, in this case is supposed to kill the running process of the OSX Pages app.
The problem is that as long as tcpdump and the until statement work perfectly fine when run separately, they do not work when piped and run together as a single script. When run together, after several seconds of what looks like the script seemingly running (but not printing the xx.xxx.xx.xx IP address, which is not as it is supposed to work), tcpdump returns:
Unable to write: Broken pipe.
Here is what I have tried so far to fix this issue:
Running
tcpdumpboth with and without| grep.Preceding the
until statementwithcat, both with;and without it, like this| cat; until [[ '! xx.xxx.xx.xx' ]], and like this| cat until [[ '! xx.xxx.xx.xx' ]].Passing
tcpdumpitself or with| grep xx.xxx.xx.xxas a variable by puttingxargsbeforeuntil, like this| xarg until [[ '! xx.xxx.xx.xx' ]].While still conjoining
tcpdumpand theuntil statementwith|, I would precedesudo tcpdumpwithcat <<EOF | tr '\12' ' 'and addEOFright underdone, in a new line, in order to be sure that when the entire command is executed, the wholeuntil statementis in a single line.Conjoining
tcpdumpand theuntil statementnot with|, but either single ampersand, like this&, or double ampersand, like this&&.Adding
| tail -n +1beforeuntil, like this:
| tail -n +1 | until.
- Putting the entire shell script inside
{and}, like this:
{ sudo tcpdump -vv -n -s 0 -k NP | grep xx.xxx.xx.xx until [[ '! xx.xxx.xx.xx' ]] do sleep 1 done killall -9 'Pages' }.
In the case of Ad. 1, over time I am returned with the said `Unable to write: Broken pipe' error.
In the case of Ad. 2, when I use cat; there is no Unable to write: Broken pipe error, and the information about the connection with the xx.xxx.xx.xx IP address is returned slower than when without cat;. Again, though, Pages is closed only when I terminate the execution of the command, and not when I terminate the connection with the xx.xxx.xx.xx IP address. When I use cat without ; instead, I am returned with zsh: parse error near do'.
In the case of Ad. 3, the whole command also returns zsh: parse error near do'.
In the case of Ad. 4, Terminal treats all the three pipes and the until part of the until statement as a directory, switching from the home directory to pipe pipe pipe until>.
In the case of Ad. 5, although slower than it should be, the script seems to be running, the connection with the xx.xxx.xx.xx IP address is printed out line by line, and no Unable to write: Broken pipe error is returned, but when I terminate the connection with the xx.xxx.xx.xx IP address, the until statement does not react to it, and Pages dossn‘t get killed. Again, Pages is closed only when I terminate the execution of the command.
In the case of Ad. 6, the Terminal gets stuck at:
tcpdump: data link type PKTAP tcpdump: listening on pktap, link-type PKTAP (Apple DLT_PKTAP), snapshot length 524288 bytes
of tcpdump for a long time, and Pages gets closed even with the entire script seemingly running, without even terminating it. Only after even more time of waiting does the Terminal return the Unable to write: Broken pipe error.
In the case of Ad. 7, although tcpdump returns the information about the connection at the normal speed, just like in the case of Ad. 1, nothing other than that happens. Pages does not get closed whatsoever, not even when I terminate the execution of the command like in the previous examples. Putting the closing } higher, that is, right after done, like this done }, changes nothing, and the result is exactly the same.
Since the Terminal interpreter I am using is the currently default zsh interpreter, I thought I would debug the entire command by using the zsh debugger, acronymed to zshdb. When I save the entire command as in Ad. 1 to a shell script file named tcpdumpuntil.sh, make it an executable file with the use of the chmod a+x and debug it by entering zshdb ./tcpdumpuntil.sh in the Terminal and executing it, the only piece of information about the correctness or not of the entire command that zshdb returns is zsh<0>. It doesn‘t return anything else and, as far as I understand, the <0> value means that the execution of the command is true, meaning that there are no errors in the overall syntax and that the entire command is executed properly. The Terminal could stay at that zsh<0> value for hours, and nothing else would happen. Returning the said value, zshdb also prints out the entire command being debugged. That printed out command being debugged is printed out in a single line, which, as I understand, is also the way it should be.
If it is true, although it is only may assumption, that the entire command is properly composed and executed, what else could I do or what else should be done for tcpdump and the until statement to work together at the same time and to make the until statement react to and execute when the connection with the xx.xxx.xx.xx IP address is terminated? Is it still, in spite of everything, possible that somehow the stdout of tcpdump is not passed on to the stdin of the until statement, and that the until statement doesn‘t read it? If so, how to make the two commands indeed share the stdout of tcpdump?
I want to make it clear that I checked all the threads suggested when writing this thread, and as in some of them discussed were the solutions I had already described, which do not work in my case, the other threads did not touch upon my issue, and did not include viable solutions.
P.S. I can only add that I have also tried to pipe the above until statement with lsof -i :xx.xxx.xx.xx the same way, also to no avail
I have tried all the things as described in the main message body. My expectation is that when tcpdump finds no connection with the particular IP address, the until statement should kill the particular process indicated by causing the execution of the killall -9 command.