linux xargs命令


参数代换: xargs

回到顶部

xargs 是在做什么的呢?就以字面上的意义来看, x 是加减乘除的乘号,args 则是 arguments (参数) 的意思,所以说,这个玩意儿就是在产生某个命令的参数的意思! xargs 可以读入 stdin 的数据,并 且以空格符或断行字符作为分辨,将 stdin 的资料分隔成为 arguments 。 因为是以空格符作为分隔, 所以,如果有一些档名或者是其他意义的名词内含有空格符的时候, xargs 可能就会误判了~他的 用法其实也还满简单的!就来看一看先!

              [peter@study ~]$ xargs [-0epn] command
            
选项与参数:
-0 :如果输入的 stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数 可以将他还原成一般字符。这个参数可以用于特殊状态喔!
-e :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到这个字符串时, 就会停止继续工作!
-p :在执行每个命令的 argument 时,都会询问使用者的意思;
-n :后面接次数,每次 command 命令执行时,要使用几个参数的意思。
当 xargs 后面没有接任何的命令时,默认是以 echo 来进行输出喔!
范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 id 这个命令将每个账号内容秀出来
              [peter@study ~]$ id root
              uid=0(root) gid=0(root) groups=0(root)
            
# 这个 id 命令可以查询用户的 UID/GID 等信息
              [peter@study ~]$ id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
            
# 虽然使用 $(cmd) 可以预先取得参数,但可惜的是, id 这个命令『仅』能接受一个参数而已!
# 所以上述的这个命令执行会出现错误!根本不会显示用户的 ID 啊!
              [peter@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | iduid=1000(peter) gid=1000(peter) groups=1000(peter),10(wheel)
            
# 我不是要查自己啊!
# 因为 id 并不是管道命令,因此在上面这个命令执行后,前面的东西通通不见!只会执行 id!
              [peter@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id
            
# 依旧会出现错误!这是因为 xargs 一口气将全部的数据通通丢给 id 处理~但 id 就接受 1 个啊最多!
              [peter@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
              uid=0(root) gid=0(root) groups=0(root)
              uid=1(bin) gid=1(bin) groups=1(bin)
              uid=2(daemon) gid=2(daemon) groups=2(daemon)
            
# 透过 -n 来处理,一次给予一个参数,因此上述的结果就 OK 正常的显示啰!
范例二:同上,但是每次执行 id 时,都要询问使用者是否动作?
              [peter@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
              id root ?...y
              uid=0(root) gid=0(root) groups=0(root)
              id bin ?...y
              .....(底下省略).....
            
# 呵呵!这个 -p 的选项可以让用户的使用过程中,被询问到每个命令是否执行!
范例三:将所有的 /etc/passwd 内的账号都以 id 查阅,但查到 sync 就结束命令串
              [peter@study ~]$ cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
            
# 仔细与上面的案例做比较。也同时注意,那个 -e'sync' 是连在一起的,中间没有空格键。
# 上个例子当中,第六个参数是 sync 啊,那么我们下达 -e'sync' 后,则分析到 sync 这个字符串时,
# 后面的其他 stdin 的内容就会被 xargs 舍弃掉了!
其实,在 man xargs 里面就有三四个小范例,您可以自行参考一下内容。 此外, xargs 真的是很好 用的一个玩意儿!您真的需要好好的参详参详!会使用 xargs 的原因是, 很多命令其实并不支持管 线命令,因此我们可以透过 xargs 来提供该命令引用 standard input 之用!举例来说,我们使用如下 的范例来说明:
范例四:找出 /usr/sbin 底下具有特殊权限的档名,并使用 ls -l 列出详细属性
              [peter@study ~]$ find /usr/sbin -perm /7000 | xargs ls -l
              -rwx--s--x. 1 root lock
              11208 Jun 10
              2014 /usr/sbin/lockdev
              -rwsr-xr-x. 1 root root 113400 Mar 6 12:17 /usr/sbin/mount.nfs
              -rwxr-sr-x. 1 root root 11208 Mar 6 11:05 /usr/sbin/netreport
              .....(底下省略).....
            
# 聪明的读者应该会想到使用『 ls -l $(find /usr/sbin -perm /7000) 』来处理这个范例!
# 都 OK!能解决问题的方法,就是好方法!

关于减号 - 的用途

回到顶部

管道命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的 一环, 所以请特别留意!另外,在管道命令当中,常常会使用到前一个命令的 stdout 作为这次的 stdin , 某些命令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 "-" 来替代, 举例来说:

              [root@initroot ~]# mkdir /tmp/homeback
              [root@initroot ~]# tar -cvf - /home | tar -xvf - -C /tmp/homeback
            
上面这个例子是说:『我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送 到 stdout; 经过管道后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前 一个命令的 stdout, 因此,我们就不需要使用 filename 了!这是很常见的例子喔!注意注意!

本文由initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读