A function of mine might need to unmount someting.  If there's a problem I try to be helpful: umount -v "$mountpoint" || {     # Helpful diagnostics if partition won't unmount:     echo "\nCan't unmount $mountpoint.  Is a terminal logged on? Or is it one of these programs:?\n(Please wait or press '^C' to quit.)"     abc=$(lsof | grep $mountpoint)     abc=( ${(f)abc} )     for def in $abc[@]; do ghi=( ${=def} ); print -- "$ghi[1]\t$ghi[-1]\n"; done     return } Typical run: % mnt ,U sda Unmounting partitions ... umount: /mnt/sda/1: target is busy. Can't unmount /mnt/sda/1.  Is a terminal logged on?  Or is it one of these programs:? (Please wait or press '^C' to quit.) zsh      /mnt/sda/1/EFI/BOOT geany    /mnt/sda/1/EFI/BOOT geany    /mnt/sda/1/EFI/BOOT geany    /mnt/sda/1/EFI/BOOT ---------------------------------------------------- ... works fine but I'll bet: abc=$(lsof | grep $mountpoint) abc=( ${(f)abc} ) for def in $abc[@]; do ghi=( ${=def} ); print -- "$ghi[1]\t$ghi[-1]\n"; done ... is belabored.   Can that be streamlined?  As always my splitting is a problem.  I need to process line by line, but then word by word so as to grab just the first and last words from 'lsof' output.  I'll bet Roman can do all of the above in 20 characters.