iTerm2 is a great terminal for MacOS; far better than Apple’s built-in Terminal app, and it’s my #1 recommendation for Mac-based network engineers. One of the many reasons I like it is that it has a feature that solves a really annoying problem.
It’s tedious having to issue a command repeatedly so that you can see when and if the output changes. I’ve had to do this in the past, repeating commands like show ip arp
so that I can spot when an entry times out and when it it refreshes. The repeated sequence of up arrow, Enter, up arrow, Enter, up arrow, Enter
drives me mad.
Some vendors offer assistance; A10 Networks for example has a repeat
command in the CLI specifically to help with show commands:
a10-vMaster[2/2]#repeat 5 show arp Total arp entries: 25 Age time: 300 secs IP Address MAC Address Type Age Interface Vlan --------------------------------------------------------------------------- 10.1.1.65 0000.5e00.01a1 Dynamic 17 Management 1 10.1.1.67 ac4b.c821.57d1 Dynamic 255 Management 1 10.1.1.97 001f.a0f8.d901 Dynamic 22 Management 1 Refreshing command every 5 seconds. (press ^C to quit) Elapsed Time: 00:00:00 Total arp entries: 25 Age time: 300 secs IP Address MAC Address Type Age Interface Vlan --------------------------------------------------------------------------- 10.1.1.65 0000.5e00.01a1 Dynamic 22 Management 1 10.1.1.67 ac4b.c821.57d1 Dynamic 260 Management 1 10.1.1.97 001f.a0f8.d901 Dynamic 27 Management 1 Refreshing command every 5 seconds. (press ^C to quit) Elapsed Time: 00:00:05
I have used this feature quite a lot, and I particularly like that there’s a built-in elapsed time marker between each command. But how to do the same in NXOS (for example) which does not have the repeat
command?
iTerm2 Run Coprocess
Like many feature-rich applications, I suspect many users don’t get to try out all of iTerm2’s available features, because the base functionality is so good there’s often no need to dig much further into it than how to select a font and color. The Run Coprocess
command is one that I simply don’t hear people talk about, so let’s take a look!
The Run Coprocess
command allows a shell script or other executable to generate output which is sent as input to the terminal window. It’s easy to test by creating a shell script which uses echo
command to write text to STDOUT:
#!/bin/bash echo ls -al
Make the file executable (chmod +x <filename>
), then in a window which is at a shell prompt, run the file using Run Coprocess
:
It’s necessary to include a full path to the script, in this case my home directory, or ~/. The script runs and ls -al
is echoed to my active terminal window as if I had typed it the command prompt. Voila, a file listing!
Repeating Commands
If I extend the logic above, it should be easy to create a script which will issue the ‘show ip arp’ command at a known interval and, to get a timestamp, how about I add a ‘show clock’ command first too?:
#!/bin/bash while true; do echo show clock echo show ip arp sleep 5 done
Since this script will loop forever, it is probably a good time to mention how to stop a Coprocess:
Does it work? You bet:
nxos-sw1# show clock 15:59:06.009 UTC Sat Oct 07 2017 nxos-sw1# show ip arp Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean D - Static Adjacencies attached to down interface IP ARP Table for context default Total number of entries: 2 Address Age MAC Address Interface 192.168.129.18 00:10:11 00a7.420b.0570 Vlan1984 192.168.129.14 00:10:51 00c1.647f.9ac0 Vlan1983 nxos-sw1# show clock 15:59:11.013 UTC Sat Oct 07 2017 nxos-sw1# show ip arp Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean D - Static Adjacencies attached to down interface IP ARP Table for context default Total number of entries: 2 Address Age MAC Address Interface 192.168.129.18 00:10:16 00a7.420b.0570 Vlan1984 192.168.129.14 00:10:56 00c1.647f.9ac0 Vlan1983
Bearing in mind that Cisco IOS/NXOS/XR all ignore commands beginning with a !
, the timestamp generation could even be moved into the script:
#!/bin/bash while true; do echo ! `date` echo show ip arp sleep 5 done
And the result is as you’d hope:
nxos-sw1# ! Sat Oct 7 12:03:26 EDT 2017 nxos-sw1# show ip arp vrf prod
This is helpful because now I can create a repeating command tool for Cisco devices which will issue a timestamp, issue any command I want, and repeat with whatever interval I choose as well:
#!/bin/sh # Call as repeatcmd.sh# Get text to output from args CMD=$1 # Check that a command was supplied if [[ $CMD == "" ]]; then exit fi # Default timeout is 3s REPEAT=3 # ...but if you set a 2nd arg which is >0, that's the new repeat timer if [ $2 > 0 ]; then REPEAT=$2 fi # Send the command text every $REPEAT seconds while true; do echo ! `date` echo $CMD sleep $REPEAT done
As long as the command argument ($1) is issued as a single string (use quotes!) I can now trigger any command:
And the result:
us-atl01-z1fa07a# ! Sat Oct 7 12:09:01 EDT 2017 us-atl01-z1fa07a# show ip arp vrf prod Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean D - Static Adjacencies attached to down interface IP ARP Table for context default Total number of entries: 2 Address Age MAC Address Interface 192.168.129.18 00:01:24 00a7.420b.0570 Vlan1984 192.168.129.14 00:02:04 00c1.647f.9ac0 Vlan1983 us-atl01-z1fa07a# ! Sat Oct 7 12:09:03 EDT 2017 us-atl01-z1fa07a# show ip arp Flags: * - Adjacencies learnt on non-active FHRP router + - Adjacencies synced via CFSoE # - Adjacencies Throttled for Glean D - Static Adjacencies attached to down interface IP ARP Table for context default Total number of entries: 2 Address Age MAC Address Interface 192.168.129.18 00:01:26 00a7.420b.0570 Vlan1984 192.168.129.14 00:02:06 00c1.647f.9ac0 Vlan1983
Note that the timestamps are 2 seconds apart. The unix sleep command is pretty vague about how precise it will be (thus we assume that’s going to sleep for around two seconds in this case), but with a timestamp to confirm, at least I’ll know what the delay actually was.
Handy, right? I think so. What other uses do you have for a terminal Coprocess?
if you are in MacOSX you have the luxury of nearly unlimited ‘co-processes’ — you are running a bash (or other) unix shell!
You are already writing the looping bash scripts- why not use bash’s ability to run sub-shells (cmd-Z) to do everything you are doing without your hands leaving the keyboard (to click on menus)?
Unless I missing something the bash shell itself is way more powerful than iTerm2.
Many people don’t explore the other parts of iTerm2 because they are mostly redundant- Apple’s terminal is a very nice gateway into the power and control of the bash shell.