inspect .zip contents from command line

If you are browsing around in a terminal and want to see the contents of a .zip file, unzip is able to just list the contents but not actually extract them:

unzip -l myarchive.zip

Alternatively, if you want to open a .zip file in a GUI window to browse it’s contents do this:

file-roller myarchive.zip

It will open up Archive Manager to look at the contents.

mount iso file in linux

I had to copy the contents of a .iso file. It’s easy to mount it and see what’s in the iso.


# mkdir /mnt/iso
# mount -o loop VMware-VMvisor-Installer-5.1.0-799733.x86_64.iso /mnt/iso
# cd /mnt/disk
# ls
a.b00         ata_pata.v05  boot.cfg      ima_qla4.v00  isolinux.bin  misc_dri.v00  net_e100.v01  net_r816.v00  ohci_usb.v00  sata_sat.v02  scsi_bnx.v00  scsi_meg.v01  scsi_qla.v01  upgrade                  xlibs.v00
ata_pata.v00  ata_pata.v06  chardevs.b00  imgdb.tgz     isolinux.cfg  net_be2n.v00  net_enic.v00  net_r816.v01  safeboot.c32  sata_sat.v03  scsi_fni.v00  scsi_meg.v02  scsi_rst.v00  user.b00                 xorg.v00
ata_pata.v01  ata_pata.v07  efi           imgpayld.tgz  k.b00         net_bnx2.v00  net_forc.v00  net_s2io.v00  sata_ahc.v00  sata_sat.v04  scsi_hps.v00  scsi_mpt.v00  s.v00         useropts.gz
ata_pata.v02  b.b00         efiboot.img   ipmi_ipm.v00  mboot.c32     net_bnx2.v01  net_igb.v00   net_sky2.v00  sata_ata.v00  scsi_aac.v00  scsi_ips.v00  scsi_mpt.v01  tboot.b00     vmware-esx-base-osl.txt
ata_pata.v03  block_cc.v00  ehci_ehc.v00  ipmi_ipm.v01  menu.c32      net_cnic.v00  net_ixgb.v00  net_tg3.v00   sata_sat.v00  scsi_adp.v00  scsi_lpf.v00  scsi_mpt.v02  tools.t00     vmware-esx-base-readme
ata_pata.v04  boot.cat      esx_dvfi.v00  ipmi_ipm.v02  misc_cni.v00  net_e100.v00  net_nx_n.v00  net_vmxn.v00  sata_sat.v01  scsi_aic.v00  scsi_meg.v00  scsi_qla.v00  uhci_usb.v00  weaselin.t00
#

Now the contents of /mnt/disk appear as if you had burned the .iso and put it in the CD drive.

make many directories with Bash sequences

Sometimes it’s necessary to do things with sequences in Bash. If you want to create a bunch of directories that will be mount points for NFS servers you could do this:


# mkdir /mnt/fs42
# mkdir /mnt/fs42/vol0
# mkdir /mnt/fs42/vol1
# mkdir /mnt/fs42/vol2
# mkdir /mnt/fs42/vol3

But, even the best experts at the “up arrow key” wouldn’t want to do this for 50 file servers. A nested for loop would work, but it’s not necessarily the easiest way to go. The command seq makes a sequence of integers bounded by the numbers specified.

ok:

for i in `seq 1 50`; do for j in `seq 0 3`; do mkdir -p /mnt/fs$i/vol$j; done; done;

Using Bash sequences, you can tell the shell to interpret this {1..50} as a list of integers between 1 and 50. This also works with letters like {a..t}.

# echo {a..t}
a b c d e f g h i j k l m n o p q r s t
# echo {0..50}
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

way better:


# mkdir -p /mnt/fs{1..50}/vol{0..3}

of course if you have non-sequential lists, you may have to specify each element like this:

{1,3,4,5,6,9}

rsync on different ssh port

By default ssh runs on TCP port 22. If you have a ssh configured to listen on a non standard port, you may need a special option to make rsync connect to that port. I was writing a quick backup script for this worpress site, and ran into this issue. In my case I was trying to rsync to a remote server with ssh listening on 4590. You have to give rsync a special ssh option:

# rsync -a --rsh='ssh -p 4590' /srv/www/wp-uploads/ backupsite.com:/backups/wp/wp-uplodas

find recently modified files

To find the 10 newest items in your home directory you can just use ls.

# cd 
# ls -lt | head
total 1197116
-rw-r--r--  1 fordodone     fordodone        5353 2013-04-23 10:42 file1
-rw-r--r--  1 fordodone     fordodone        2945 2013-04-23 10:21 file2
drwxr-xr-x  2 fordodone     fordodone       12288 2013-04-12 08:53 bin
-rw-r--r--  1 fordodone fordodone         0 2013-03-27 08:45 file3
-rw-------  1 fordodone fordodone     90420 2013-03-23 09:03 file4
-rw-r--r--  1 fordodone     fordodone          83 2013-03-19 10:35 file5
-rw-r--r--  1 fordodone     fordodone        8683 2013-03-15 10:26 file6
-rw-r--r--  1 fordodone     fordodone       28628 2013-03-15 09:15 file7
-rw-r--r--  1 fordodone     fordodone       81303 2013-03-15 09:15 file8

You could even get more aggressive by throwing the recursive flag in. Simple, right? But what if you need to recurse a large number of files and directories on a storage system, say 123,000 directories and 37 million files. I think find might be the way to go.

This will find files modified in the last 24 hours:

# find . -type f -mtime -1 -ls

find doesn’t really provide granular control of searching for files with a certain modified time. If you just want to find files that have been modified today (i.e. since 12am) we can use the -newer flag. First touch a temporary file with a timestamp to compare to files you want to find. In this case we make a date string of 04240000, or today at 00:00, and touch a file with that timestamp. Then use find to find files that are newer than the timestamp of the file you just touched.


# touch -t `date +%m%d0000` /tmp/compare
# find . -type f -newer /tmp/compare
(long output)
# rm /tmp/compare

troubleshoot UDP connectivity

When troubleshooting network connectivity issues the best method is to begin with the lower layers of the OSI model and work your way up until you eliminate the problem. It’s similar to the way some people troubleshoot helpdesk issues, where the first question is always “is it plugged in?”

Suppose you have 2 hosts, and you are trying to do an snmp query from one to the other. It doesn’t work.

# snmpwalk -v2c -c public 10.210.0.142 
Timeout: No Response from 10.210.0.142

You try pinging one from the other and you get replies. At this point you know that everything is working through layer 3, but something is not right with the transport layer. If you were troubleshooting a TCP based application, you could just use ol’ telnet to test if the port will open up. To see if a webserver is running you could try to telnet to port 80. UDP is a connectionless protocol, and can’t be tested like TCP. Here is where you can use nmap to see if the UDP port in question is open. In this case we know that by default snmpd listens on UDP 161.

# nmap -sU -v -p161 10.210.0.142

Starting Nmap 5.00 ( http://nmap.org ) at 2013-04-24 11:27 MST
NSE: Loaded 0 scripts for scanning.
Initiating ARP Ping Scan at 11:27
Scanning 10.210.0.142 [1 port]
Completed ARP Ping Scan at 11:27, 0.03s elapsed (1 total hosts)
Initiating UDP Scan at 11:27
Scanning example.fordodone.com (10.210.0.142) [1 port]
Completed UDP Scan at 11:27, 0.07s elapsed (1 total ports)
Host example.fordodone.com (10.210.0.142) is up (0.00100s latency).
Interesting ports on example.fordodone.com (10.210.0.142):
PORT    STATE  SERVICE
161/udp closed snmp
MAC Address: 00:0C:29:A2:BE:4D (VMware)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.43 seconds
           Raw packets sent: 2 (70B) | Rcvd: 2 (98B)

Well, there you go. The port is closed. No wonder our queries were timing out. Remove the -p161 part to just scan for all open UDP ports. Also, if your host doesn’t allow icmp, you can use -P0 to just skip host discovery, and assume it’s up. Depending whether they are open, filtered, or closed, you can start to diagnose what’s going on, i.e. snmpd crashed, firewall is blocking it, etc.

print last 3 characters of a string

If you need to get the last few characters of a string, you can just use awk.  This works great because you don’t have to know how long or short the string is to begin with. It first gets the length of the string. So in this example the length is 9 characters, and the ‘1’ would be in position 9 of the string. Then it subtracts 2 from position 9, to get position 7 (which is the ‘3’), then it gets 3 characters starting from position 7: ‘371’

# echo server371 | awk '{print substr($0,length($0)-2,3)}'
371

# echo anotherserver892 | awk '{print substr($0,length($0)-2,3)}'
892