Sockets in Your Shell
who23.github.io
who23.github.io
if [ exec 1>/dev/null 2>/dev/null 3>/dev/tcp/localhost/4000 ] ; then
This code runs `[ exec ]` (which tests if "exec" is a non-empty string, thus it returns true) and redirects its output and error to /dev/null, and fd 3 to /dev/tcp/whatever. If the socket opening fails, `[ exec ]` is not even executed, and the overall command returns nonzero. Completely equivalent to `: 3>/dev/tcp/localhost/4000`, which also returns nonzero if the socket can't be opened.It happens to work for the intended purpose, but not for the reasons the author intended.
In exec.sh line 1:
if [ exec 1>/dev/null 2>/dev/null 3>/dev/tcp/localhost/4000 ] ; then
^-- SC1009: The mentioned syntax error was in this if expression.
^-- SC1073: Couldn't parse this test expression. Fix to allow more checks.
^-- SC1014: Use 'if cmd; then ..' to check exit code, or 'if [[ $(cmd) == .. ]]' to check output.
^-- SC1072: Expected test to end here (don't wrap commands in []/[[]]). Fix any mentioned problems and try again.
For more information:
https://www.shellcheck.net/wiki/SC1014 -- Use 'if cmd; then ..' to check ex...
https://www.shellcheck.net/wiki/SC1072 -- Expected test to end here (don't ...
https://www.shellcheck.net/wiki/SC1073 -- Couldn't parse this test expressi... #!/bin/bash
if exec 3>/dev/tcp/localhost/4000 ; then
echo "server up!"
else
echo "server down."
fi
Which also confused me for similar reasons to your comment. I'm not familiar with exec, but generally non-zero return means a fail, and zero means success. So why is the "server up" for non-zero result? > exec 3>/dev/tcp/localhost/4000
bash: connect: Connection refused
bash: /dev/tcp/localhost/4000: Connection refused
> echo $?
1
But if a localhost port is listening (in another terminal window: > nc -l localhost 4000): > exec 3>/dev/tcp/localhost/4000
> echo $?
0 > if true; then echo yup; fi
yup
> true
> echo $?
0 if [ $? -eq 0 ]; then echo "pass";else echo "fail";fi
But without the expression '[ ... ]' shell/bash does indeed treat zero return code (success) as boolean true.
For whatever reason I have not seen much (if any) bash code that simply uses: if COMMAND; then ...It also works for shell functions.
if [ $? -eq 0 ]; then ...
is actually an instance of if COMMAND; then ...
because [ is itself a command.I leveraged this some time ago to sent WOL packets. I think it went something like:
echo -e [16 times the target MAC written as \xFF] > /dev/udp/255.255.255.255/9
BTW, I'm not entirely sure how broadcast IPv4 addresses work. I think they are set by the DHCP server, and the computer sends packets to these addresses as MAC broadcasts? (leaving the dest IP as the configured broadcast one).Once the packet arrives at the destination subnet (which can be immediately or several routing hops away) it will (in the case of Ethernet) you're right that's to the FF:FF:FF:FF:FF:FF destination MAC.
In the case of DHCP client <-> server on different subnets there is a special "DHCP relay" role configured in the network and that relay is what handles broadcast to unicast conversions https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Pro...
Note that GNU doesn't have a netcat implementation. There's a netcat implementation that calls itself "GNU netcat", but it isn't actually associated with GNU, and the authors are jerks for naming it that.
But also, there are more netcat implementations than just 2!
- OpenBSD netcat
- "GNU" Netcat (http://netcat.sourceforge.net)
- BusyBox netcat
- Nmap's `ncat`
- Netcat6 (http://www.deepspace6.net/projects/netcat6.html)
And all of them are just different enough from eachother...
I like the fact that Solaris netcat supports socks proxies, that's really useful, especially in combination with `ssh -D`.
{
netdir=/net/tcp/`{cat}
echo connect $ip!$port >$netdir/ctl || exit 'cannot connect'
echo GET / HTTP/1.1 > $netdir/data
echo > $netdir/data
cat $netdir/data
} < /net/tcp/clone
It used for example in IRC client implemented in rc shell
http://web.archive.org/web/20060620053701/http://plan9.bell-...https://github.com/swisskyrepo/PayloadsAllTheThings/blob/mas...
This being a bash-ism is really misleading. This looks as if my computer has device nodes for $PROTO, and I suppose that's not the case. I think it would make more sense as (optional) /dev nodes giving all programs access to it.
But that's really just a bit of wishful thinking -- those files/directories don't exist on any mainstream UNIX OS I'm aware of.
https://blog.sleeplessbeastie.eu/2020/05/27/how-to-disable-n...
with open('/dev/tcp/127.0.0.1/8000') as f:
d = f.read()
...http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-...
The difference seems to be that zsocket works with Unix domain sockets and, only for incoming connections, sockets already opened and with a file descriptor. I suppose this latter one can be used for any kind of socket if opened before exec'ing zsh.
Tiny typo:
> For example, if a local build of a web app runs on port 8000 [...]
8000 --> 4000
cat /dev/https/news.ycombinator.com | grep -i shell¹ http://manpages.ubuntu.com/manpages/latest/en/man1/httpfs2.1...
Looking at https://sources.debian.org/src/bash/5.0-4/debian/changelog/#...,
bash (4.0-5) unstable; urgency=low
* Re-add dependency on dash, lost with the upload of 4.0.
* Don't configure with --disable-net-redirections.
* Fix name of system wide bash_logout in bash(1). Closes: #546200.
* Stop shipping the sh and sh(1) symlinks. Closes: #545103.
* Apply upstream patches 029 - 033.
-- Matthias Klose <doko@debian.org> Sun, 13 Sep 2009 12:55:54 +0200
it seems net-redirections has been reenabled more than a decade ago.