I saw the 5-Jun-2023 blog post on changes in ROOT, including the web-based version of TBrowser. This would greatly simplify my ROOT tutorial, so I decided to give it a try.
I’m using a Apple Studio M1 running Mac OS Ventura 13.4. I use Homebrew as a package manager. I ran:
brew install root
brew install netcat
(I discovered that I needed the latter after I tried rootssh for the first time.) I then tried to run rootssh:
# rootssh seligman@myserver.nevis.columbia.edu
Use local port 7575 for root_socket /tmp/root.sbU8XwGu0 redirection from seligman@myserver.nevis.columbia.edu
netcat: invalid option -- U
Try `netcat --help' for more information.
Command not recognized - stop
The remote machine myserver is running AlmaLinux 9, 6.28/04, Built for linuxx8664gcc, g++ (GCC) 11.3.1. I also installed netcat on the remote server, just in case, but that changed nothing.
Sure enough, when I type netcat --help and man netcat on both systems, the Homebrew version of netcat does not have the -U option, though the Linux version does.
A quick glance using:
less `which rootssh`
shows that indeed the command netcat -U is part of the script, with no tests against program or OS version, or whether the program is capable of handling UNIX-domain sockets.
Am I doing something wrong? Is this a bug in rootssh? Or am I missing something?
ROOT Version: 6.28/04 Platform: MacOS Ventura 13.4, Built for macosxarm64 Compiler: Apple clang version 14.0.3
Historically, there is more than one implementation of netcat, most importantly the GNU and the OpenBSD one. I guess rootssh relies on the latter, which allows to use UNIX domain sockets via the -U option.
(FYI, @linev)
However, macOS should already bundle the BSD version as /usr/bin/nc – therefore, in principle, no need to install the netcat package from brew.
Given that on most systems where netcat is installed, nc is a symlink to netcat, perhaps we should use nc in the rootssh script instead, @linev (?).
# which nc
/usr/bin/nc
# which netcat
/opt/homebrew/bin/netcat
# netcat --help
GNU netcat 0.7.1, a rewrite of the famous networking tool.
Basic usages:
connect to somewhere: netcat [options] hostname port [port] ...
listen for inbound: netcat -l -p port [options] [hostname] [port] ...
tunnel to somewhere: netcat -L hostname:port -p port [options]
Mandatory arguments to long options are mandatory for short options too.
Options:
-c, --close close connection on EOF from stdin
-e, --exec=PROGRAM program to exec after connect
-g, --gateway=LIST source-routing hop point[s], up to 8
-G, --pointer=NUM source-routing pointer: 4, 8, 12, ...
-h, --help display this help and exit
-i, --interval=SECS delay interval for lines sent, ports scanned
-l, --listen listen mode, for inbound connects
-L, --tunnel=ADDRESS:PORT forward local port to remote address
-n, --dont-resolve numeric-only IP addresses, no DNS
-o, --output=FILE output hexdump traffic to FILE (implies -x)
-p, --local-port=NUM local port number
-r, --randomize randomize local and remote ports
-s, --source=ADDRESS local source address (ip or hostname)
-t, --tcp TCP mode (default)
-T, --telnet answer using TELNET negotiation
-u, --udp UDP mode
-v, --verbose verbose (use twice to be more verbose)
-V, --version output version information and exit
-x, --hexdump hexdump incoming and outgoing traffic
-w, --wait=SECS timeout for connects and final net reads
-z, --zero zero-I/O mode (used for scanning)
Remote port number can also be specified as range. Example: '1-1024'
# nc --help
nc: unrecognized option `--help'
usage: nc [-46AacCDdEFhklMnOortUuvz] [-K tc] [-b boundif] [-i interval] [-p source_port]
[--apple-recv-anyif] [--apple-awdl-unres]
[--apple-boundif ifbound]
[--apple-no-cellular] [--apple-no-expensive]
[--apple-no-flowadv] [--apple-tcp-timeout conntimo]
[--apple-tcp-keepalive keepidle] [--apple-tcp-keepintvl keepintvl]
[--apple-tcp-keepcnt keepcnt] [--apple-tclass tclass]
[--tcp-adp-rtimo num_probes] [--apple-initcoproc-allow]
[--apple-tcp-adp-wtimo num_probes]
[--setsockopt-later] [--apple-no-connectx]
[--apple-delegate-pid pid] [--apple-delegate-uuid uuid]
[--apple-kao] [--apple-ext-bk-idle]
[--apple-netsvctype svc] [---apple-nowakefromsleep]
[--apple-notify-ack] [--apple-sockev]
[--apple-tos tos] [--apple-tos-cmsg]
[-s source_ip_address] [-w timeout] [-X proxy_version]
[-x proxy_address[:port]] [hostname] [port[s]]
It’s as you said: netcat doesn’t have the -U option in Homebrew, but nc has the -U option in Darwin.
I suppose as a work-around I could try removing the Homebrew netcat, then alias netcat to nc. I may give it a try later.
I gave it a try. An alias did not work (since rootssh runs in a sub-shell) so I used a symbolic link instead. However, I got stuck on a different step:
# cd /opt/homebrew/bin
# /opt/homebrew/bin > ln -sf /usr/bin/nc netcat
# /opt/homebrew/bin > cd
# rootssh seligman@myserver
Use local port 7221 for root_socket /tmp/root.mH1CbHzTo redirection from seligman@myserver
[07:11:47][myserver:~]$ root
------------------------------------------------------------------
| Welcome to ROOT 6.28/04 https://root.cern |
| (c) 1995-2022, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for linuxx8664gcc on May 08 2023, 02:44:07 |
| From tags/v6-28-04@v6-28-04 |
| With g++ (GCC) 11.3.1 20221121 (Red Hat 11.3.1-4) |
| Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] TBrowser tb
ROOT comes with a web-based browser, which is now being started.
Revert to TBrowser by setting "Browser.Name: TRootBrowser" in rootrc file or
by starting "root --web=off"
Web-based TBrowser can be used in batch mode when starting with "root -b --web=server:8877"
Find more info on https://root.cern/for_developers/root7/#rbrowser
Info in <THttpEngine::Create>: Starting HTTP server on port x/tmp/root.mH1CbHzTo
/opt/homebrew/bin/rootssh: line 59: xdg-open: command not found
netcat: Address already in use
Command not recognized - stop
(TBrowser &) Name: Browser Title: ROOT Object Browser
Evidently rootssh expects to find xdg-open on the local operating system. I checked, and the xdg-open command is not available via Homebrew. There is a complicated procedure for getting xdg-open installed, but it seems like a “cure worse than the disease”:
Looking at the rootssh script, it looked like I could use a browser other than xdg-open. But I can’t figure out the argument parsing:
# rootssh --browser=firefox seligman@myserver
Use local port 7768 for root_socket /tmp/root.bjWwedX2d redirection from seligman@tanya
seligman@myserver: illegal option -- -
usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
[-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
[-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
[-i identity_file] [-J [user@]host[:port]] [-L address]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-Q query_option] [-R address] [-S ctl_path] [-W host:port]
[-w local_tun[:remote_tun]] destination [command [argument ...]]
/opt/homebrew/bin/rootssh: line 149: 25070 Killed: 9 $0 --as-listener-- $listener_local $localport $browser
# rootssh seligman@myserver --browser=firefox
Use local port 7689 for root_socket /tmp/root.7luRvsrcQ redirection from seligman@myserver
bash: line 1: --browser=firefox: command not found
Connection to myserver closed.
/opt/homebrew/bin/rootssh: line 149: 25096 Killed: 9 $0 --as-listener-- $listener_local $localport $browser
I’m looking for a process that makes the students’ lives easier, not a lesson in package dependencies.
I’m going to make a guess: rootssh has only been tested from a local Linux system to a remote Linux system. Since most of my students have either Mac or Windows laptops, may I request that the rootssh script accommodate those systems as well?
Yes, xdg-open is a Freedesktop.org thing (Linux only, I guess). Given that it depends on the XDG specification, I would not try to install it on anything that is not GNU/Linux.
xdg-open basically takes care of spawning the associated application to deal with the specified file/URL. Given that it is the used in rootssh to open the default browser, I guess you can achieve the same effect by using the macOS open command as in:
$ rootssh --browser open seligman@myserver
I will create a GitHub issue to improve the rootssh script on macOS (CC: @linev).
Because I’m so used to the classic TBrowser, this new web-based TBrowser is confusing to me. In particular, I find that the TreeViewer is not intuitive. But that’s another topic altogether.
Thanks for the rapid response, Sergey. Unfortunately, I think you’re going to need fancier scripting. I tried it, but got the “xdg-open: command not found” message again.
The issue is that your script tests against the variable $OSTYPE. On my remote Linux server, it has this value:
# echo $OSTYPE
linux-gnu
On my Mac desktop:
echo $OSTYPE
darwin22.0
While I suppose you can modify your code to just look for ‘darwin’ as a substring, might I suggest an “evidence-based” approach that might be applicable to a greater range of operating systems? Something like:
browser=""
# List of potential local client browsers
browsers=( xdg-open open )
for b in "${browsers[@]}"
do
# test if the browser is available.
which ${b} 2>&1 >/dev/null
if [ $? -eq 0 ]; then
# The search was successful.
browser=${b}
break
fi
done
if [ -z "${browser}" ]; then
echo "No appropriate browser found; please use --browser option"
exit 1
fi
That way, when we learn which ‘browser’ is appropriate for Windows or WSL, you can just add it to the browsers array and not clutter your script with a bunch of nested if statements. (Hmm… can a bash script even execute in the Windows command shell?)