Bash Index : X - The 'X' Bash commands : description, flags and examples

mail

xz

Installed with the Debian package

xz-utils

Usage

Compress or decompress .xz and .lzma files

Flags

Flag Usage
--decompress (explicit)

Example

compress a file
xz path/to/file
decompress a file
xz --decompress path/to/file.xz
mail

xxd

Usage

make a hex dump or do the reverse
So far, I'm only considering this tool in the context of URL encoding/decoding.

Flags

Flag Usage
-p -plain output result in PostScript continuous hex dump style aka plain
-r -revert convert hex dump into binary

Example

convert ASCII characters into their hexadecimal code :

For reference, we'll play with the H character, which has the 48 hexadecimal value in the ASCII table
echo -n 'H' | xxd -p
48

echo -n '\x48' | xxd -r -p
H
Same thing with [BACKSPACE] aka \x08 :
echo -n 'ABC'; echo -n '\x08' | xxd -r -p
AB
mail

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

When receiving results piped from find, xargs outputs the error :
find | xargs
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
When I got this error, some of the returned files actually had single quotes ' in their path / name / both (not checked whether the number of quotes was even or not in the path / name / both : xargs seemed unhappy anyway).
Trying the -0 option alone as "suggested" by the error message won't fix anything : it will turn the n find results (file names) into a unique giant result which is the concatenation of all the file names (read more in the solution below).

Workaround

Instead of using a construct such as :
find | xargs
consider a while read with process substitution construct :
while read fileName; do
	# do something
done < <(find )

Solution

You may use xargs' -0 option provided find feeds it correctly :
find -print0 | xargs -0
mail

xargs

Usage

Construct argument lists and invoke utility : xargs options utility
xargs may return exit codes such as 123, 124, 125, 126 or 127 if something went wrong when calling 'utility' (for details : ).

Different kinds of lists :

  • "chained" lists, aka whitespace-separated lists :
    echo 'a b c'
    a b c
  • "stacked" lists, aka newline-separated lists :
    echo -e 'a\nb\nc'
    a
    b
    c
There is no such distinction between list types, but I use these to make examples below easier to explain.
By default, xargs reads stacked lists.

Flags

Flag Usage
-0
  • input items are terminated by a null character instead of by whitespace
  • quotes and backslash are not special (every character is taken literally)
  • disables the end of file string, which is treated like any other argument
Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode.
-I pattern
-L n
  • use at most n nonblank input lines per command line
  • trailing blanks cause an input line to be logically continued on the next input line
  • implies -x
examples : -L, -L 1
-n n Pop n arguments at a time from the list to feed utility
-P n Execute at most n parallel instances of utility. Defaults to 1. (source).
-n should be specified when using -P or there is a risk of firing only 1 instance of utility.
-s maxChars
--max-chars=maxChars
  • use at most maxChars characters per command line
  • default value is system-dependant, no idea how to get it exactly
-x exit if the size specified with -s is exceeded

Example

Using -L :

echo -e {a..z}"\n" | xargs -L 12 echo
a b c d e f g h i j k l
m n o p q r s t u v w x
y z
echo -e 'a\nb\nc\nd\ne' | xargs -L 2 echo
a b
c d
e
echo -e 'a\nb \nc\nd\ne' | xargs -L 2 echo
a b c
d e

Using -L 1 :

echo -e 'a\nb\nc' | xargs -L 1 echo
a
b
c
echo -e 'a\nb\nc' | xargs -I foo echo foo
a
b
c
echo 'a b c' | xargs -L 1 echo
a b c
echo 'a b c' | xargs -I foo echo foo
a b c

tar all files of the current directory :

find -maxdepth 1 -type f | xargs tar cf archive.tar

Download all URLs listed in a file (source) :

cat urlList.txt | xargs wget -c
This example, albeit quite functional, is actually deprecated by wget's -i.

Archive the n latest files matching pattern :

ls -t *pattern* | head -n n | xargs tar cfz /path/to/archive.tgz

Cannot umount a filesystem because of open files ? Kill, kill, KILL !!! :

Killing so many processes this way is VERY! BAD!. Do this only if :

  • these processes are started at boot time
  • AND you can not switch to a lower runlevel
  • AND you can not stop them all
  • AND you plan to reboot shortly
  • AND (many other reasons to convince you this is a bad thing )

lsof /mnt/myFilesystem | awk '{print $2}' | sed '1d' | xargs kill -15

How to use the values piped to xargs into its sub-command ?

for i in {1..5}; do echo $i; done | xargs -I pattern echo 'this is line pattern.'
Looks like xargs substitutions have precedence over Bash.

To use values more than once :

for i in {a..e}; do echo $i; done | xargs -I whatIWant sh -c 'echo -n "I can say \"whatIWant\"."; echo " And I can say it even louder : \"$(echo whatIWant | tr '[:lower:]' '[:upper:]') !\""'
sh -c 'someCommand' above means run someCommand within the /bin/sh shell. Some advanced commands / flags / options may not be available in this shell. Consider bash -c 'someCommand' then.