您的位置:首页 > 运维架构 > Shell

shell 知识点补充(2)-重定向/ ; , &&, ||/管线命令/grep/sort/ uniq/wc/tee/tr/col/join/paste/expand/split/-

2012-10-18 16:45 585 查看
1、重定向

1. 标准输入(stdin) :代码为 0 ,使用 < 或 << ;(重写或追加)

2. 标准输出(stdout):代码为 1 ,使用 > 或 >> ;

3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;

eg:

yee@Loong:~$ ifconfig > 1.txt

yee@Loong:~$ vim 1.txt

yee@Loong:~$ ls -al 2.txt >>1.txt

ls: 无法访问 2.txt: 没有那个文件或目录

yee@Loong:~$ ls -al 2.txt 2>>1.txt

yee@Loong:~$ vim 1.txt

yee@Loong:~$ ls -al 1.txt 2.txt 2>>1.txt 错误的数据追加到1.txt

-rw-r--r-- 1 yee yee 922 10-18 08:56 1.txt

• 1> :是将正确的数据输出到指定的地方去

• 2> :是将错误的数据输出到指定的地方去

如果我只要正确的数据,错误的信息我不要了呢?呵呵,这个时候 /dev/null 这个垃圾桶就很重要了!/dev/null 是什么呢? 基本上,那就有点像是一个『黑洞』的垃圾桶功能!当你输入的任何东西导向到这个虚拟的垃圾桶装置时, 『他就会凭空消失不见了~~』,这个东西有用的很!例如上面的例子中,我们可以这么做,来将错误的信息丢掉!

[dmtsai@linux ~]$ find /home -name testing > list_right 2> /dev/null

error message 就会『不见了!』另外, 如果我要将数据都写到同一个档案中呢?这个时候写法需要用到特殊写法,请注意底下的写法呦!

[dmtsai@linux ~]$ find /home -name testing > list 2> list <==错误写法

[dmtsai@linux ~]$ find /home -name testing > list 2>&1 <==正确写法

请特别留意这一点!同时写入同一个档案需要使用 2>&1 才对

< 又是什么呀!?呵呵!以最简单的说法来说, 那就是『将原本需要由键盘输入的数据,经由档案来读入』的意思。 举例来说,我们可以使用 cat 在键盘上面输入一些数据,然后写入一个档案内,例如:

[root@linux ~]# cat > catfile

testing

cat file test

<==这里按下 [ctrl]+d 结束输入来离开!

此时就会有 catfile 这个档案产生,而且该档案的内容就是刚刚输入的内容喔。 那么,我是否可以使用其它档案来取代键盘输入呢?可以啊!这样做!

[root@linux ~]# cat > catfile < somefile

我可以先编辑 somefile ,然后再以上述的指令来将数据输出到 catfile 去呢!这样可以理解了吗? 能够理解 < 之后,再来则是怪可怕一把的 << 这个连续两个小于的符号了~ 他代表的是『结束的输入字符』的意思!举例来讲:『我要用 cat 直接将输入的讯息输出到 catfile 中, 且当输入 eof 时,该次输入就结束』,那我可以这样做:

[root@linux ~]# cat > catfile <<eof

> This is a test testing

> OK now stop

> eof <==输入这个玩意儿,嘿!立刻就结束了!

看到了吗?利用 << 右侧的控制字符,我们可以终止一次输入, 而不必输入 [crtl]+d 来结束哩!这对程序写作很有帮助喔!好了,那么为何要使用命令输出重导向呢? 这个问题一定会困扰你一下下的,如果你从来都没有写过 script 的话!好了,我们来说一说吧!

• 当屏幕输出的信息很重要,而且我们需要将他存下来的时候;

• 背景执行中的程序,不希望他干扰屏幕正常的输出结果时;

• 一些系统的例行命令(例如写在 /etc/crontab 中的档案)的执行结果,希望他可以存下来时;

• 一些执行命令,我们已经知道他可能的错误讯息,所以想以『 2> /dev/null 』将他丢掉时;

• 错误讯息与正确讯息需要分别输出时。

2、命令执行的判断依据: ; , &&, ||

在指令与指令中间利用分号 (;) 来隔开,这样一来,分号前的指令执行完后, 就会立刻接着执行后面的指令了。这真是方便啊~再来,换个角度来想, 万一我想要在某个目录底下建立一个档案,也就是说,如果该目录存在的话, 那我才建立这个档案,如果不存在,那就算了~目录是否存在可以使用一些 bash 提供的判断式功能, 但这里假设我不晓得那个指令,但我知道我可以使用 ls 来判断是否有该目录的存在, 也就是说,我可以利用 ls directoryname 判断是否存在,然后以 touch 建立一个档案, 这两个指令有相关性,那该如何写呢?呵呵!可以利用
&& 来作喔!

[root@linux ~]# ls /tmp && touch /tmp/testingagin

是否记得我们在变量的章节里面谈过这个奇怪的变数『 $? 』呢? 如果指令执行结果没有错误讯息,那就会回传 $?=0 ,如果有错误, 那回传值就不会是 0 啊!经由这样的判断,我们也可以利用 && 来决定, 当前面的指令执行结果为正确 (例如:仅有 standard output 时),就可以接着执行后续的指令, 否则就予以略过!因此,当 ls /tmp 没有问题,那么就会接着执行 touch /tmp/testingagin 了! 万一是这样:

[root@linux ~]# ls /vbird && touch /vbird/test

因为我的系统里面根本就不可能存在 /vbird 这个目录呢!所以,执行 ls /vbird 就会回传错误, 那么后续的 touch /vbird/test 自然就不会动作啰!了解吗? 再换个角度来想,如果我想要当某个档案不存在时,就去建立那个档案, 否则就略过呢?很简单啊~可以这样做:

[root@linux ~]# ls /tmp/vbirding || touch /tmp/vbirding

由于指令是一个接着一个去执行的,因此,如果真要使用判断, 那么这个 && 与 || 的顺序就不能搞错~一般来说,判断式最多会有三个,也就是:

command1 && command2 || command3

而且顺序通常不会变,因为一般来说, command2 与 command3 会放置肯定可以执行成功的指令

eg:

yee@Loong:~$ ls -al 1.txt && echo "1" ||echo "2"

-rw-r--r-- 1 yee yee 93 10-18 09:13 1.txt

1

yee@Loong:~$ ls -al 3.txt && echo "1" ||echo "2"

ls: 无法访问 3.txt: 没有那个文件或目录

2

yee@Loong:~$

3、管线命令 (pipe)

这个管线命令『 | 』仅能处理经由前面一个指令传来的正确信息,也就是 standard output ( STDOUT ) 的信息,对于 stdandard error 并没有直接处理的能力

cut

cut 不就是『切』吗?没错啦!这个指令可以将一段讯息的某一段给他『切』出来~ 处理的讯息是以『行』为单位喔!底下我们就来谈一谈:

[root@linux ~]# cut -d'分隔字符' -f fields

[root@linux ~]# cut -c 字符区间

参数:

-d :后面接分隔字符。与 -f 一起使用;

-f :依据 -d 的分隔字符将一段讯息分割成为数段,用 -f 取出第几段的意思;

-c :以字符 (characters) 的单位取出固定字符区间;

范例:

范例一:将 PATH 变量取出,我要找出第三个路径。

[root@linux ~]# echo $PATH

/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/games:

[root@linux ~]# echo $PATH | cut -d ':' -f 5

# 嘿嘿!如此一来,就会出现 /usr/local/bin 这个目录名称!

# 因为我们是以 : 作为分隔符,第五个就是 /usr/local/bin 啊!

# 那么如果想要列出第 3 与第 5 呢?,就是这样:

[root@linux ~]# echo $PATH | cut -d ':' -f 3,5

范例二:将 export 输出的讯息,取得第 12 字符以后的所有字符串

[root@linux ~]# export

declare -x HISTSIZE="1000"

declare -x INPUTRC="/etc/inputrc"

declare -x KDEDIR="/usr"

declare -x LANG="zh_TW.big5"

......其它省略......

[root@linux ~]# export | cut -c 12-

HISTSIZE="1000"

INPUTRC="/etc/inputrc"

KDEDIR="/usr"

LANG="zh_TW.big5"

......其它省略......

# 知道怎么回事了吧?用 -c 可以处理比较具有格式的输出数据!

# 我们还可以指定某个范围的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!

范例三:用 last 将这个月登入者的信息中,仅留下使用者大名

[root@linux ~]# last

vbird tty1 192.168.1.28 Mon Aug 15 11:55 - 17:48 (05:53)

vbird tty1 192.168.1.28 Mon Aug 15 10:17 - 11:54 (01:37)

[root@linux ~]# last | cut -d ' ' -f 1

# 用 last 可以取得最近一个月登入主机的使用者信息,

# 而我们可以利用空格符的间隔,取出第一个信息,就是使用者账号啰!

# 但是因为 vbird tty1 之间空格有好几个,并非仅有一个,所以,如果要找出

# tty1 其实不能以 cut -d ' ' -f 1,2 喔!输出的结果会不是我们想要的。

这个 cut 实在很好用!不过,说真的,除非你常常在分析 log 档案,否则使用到 cut 的机会并不多!好了! cut 主要的用途在于将『同一行里面的数据进行分解!』, 最常使用在分析一些数据或文字数据的时候!这是因为有时候我们会以某些字符当作分割的参数, 然后来将数据加以切割,以取得我们所需要的数据。我也很常使用这个功能呢!尤其是在分析 log 档案的时候!不过, cut 在处理多空格相连的数据时,可能会比较吃力一点

grep

刚刚的 cut 是将一行讯息当中,取出某部分我们想要的,而 grep 则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:

[root@linux ~]# grep [-acinv] '搜寻字符串' filename

参数:

-a :将 binary 档案以 text 档案的方式搜寻数据

-c :计算找到 '搜寻字符串' 的次数

-i :忽略大小写的不同,所以大小写视为相同

-n :顺便输出行号

-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!

范例:

范例一:将 last 当中,有出现 root 的那一行就取出来;

[root@linux ~]# last | grep 'root'

范例二:与范例一相反,只要没有 root 的就取出!

[root@linux ~]# last | grep -v 'root'

范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏

[root@linux ~]# last | grep 'root' |cut -d ' ' -f1

# 在取出 root 之后,利用上个指令 cut 的处理,就能够仅取得第一栏啰!

grep 是个很棒的指令喔!他支持的语法实在是太多了~用在正规表示法里头, 能够处理的数据实在是多的很。

sort

sort 是很有趣的指令,他可以帮我们进行排序,而且可以依据不同的数据型态来排序喔! 例如数字与文字的排序就不一样。此外,排序的字符与语系的编码有关,因此, 如果您需要排序时,建议使用 LC_ALL=C 来让语系统一,数据排序比较好一些。

[root@linux ~]# sort [-fbMnrtuk] [file or stdin]

参数:

-f :忽略大小写的差异,例如 A 与 a 视为编码相同;

-b :忽略最前面的空格符部分;

-M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;

-n :使用『纯数字』进行排序(预设是以文字型态来排序的);

-r :反向排序;

-u :就是 uniq ,相同的数据中,仅出现一行代表;

-t :分隔符,预设是 tab 键;

-k :以那个区间 (field) 来进行排序的意思,

范例:

范例一:个人账号都记录在 /etc/passwd 下,请将账号进行排序。

[root@linux ~]# cat /etc/passwd | sort

adm:x:3:4:adm:/var/adm:/sbin/nologin

apache:x:48:48:Apache:/var/www:/sbin/nologin

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 我省略很多的输出~由上面的数据看起来, sort 是预设『以第一个』数据来排序,

# 而且预设是以『文字』型态来排序的喔!所以由 a 开始排到最后啰!

范例二:/etc/passwd 内容是以 : 来分隔的,我想以第三栏来排序,该如何?

[root@linux ~]# cat /etc/passwd | sort -t ':' -k 3

root:x:0:0:root:/root:/bin/bash

iiimd:x:100:101:IIIMF server:/usr/lib/iiim:/sbin/nologin

uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

bin:x:1:1:bin:/bin:/sbin/nologin

games:x:12:100:games:/usr/games:/sbin/nologin

# 看到特殊字体的输出部分了吧?怎么会这样排列啊?呵呵!没错啦~

# 如果是以文字型态来排序的话,原本就会是这样,想要使用数字排序:

# cat /etc/passwd | sort -t ':' -k 3 -n

# 这样才行啊!用那个 -n 来告知 sort 以数字来排序啊!

范例三:利用 last ,将输出的数据仅取账号,并加以排序

[root@linux ~]# last | cut -d ' ' -f1 | sort

sort 同样是很常用的指令呢!因为我们常常需要比较一些信息啦! 举个上面的第二个例子来说好了!今天假设你有很多的账号,而且你想要知道最大的使用者 ID 目前到哪一号了!

• uniq

如果我排序完成了,想要将重复的资料仅列出一个显示,可以怎么做呢?

[root@linux ~]# uniq [-ic]

参数:

-i :忽略大小写字符的不同;

-c :进行计数

范例:

范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;

[root@linux ~]# last | cut -d ' ' -f1 | sort | uniq

范例二:承上题,如果我还想要知道每个人的登入总次数呢?

[root@linux ~]# last | cut -d ' ' -f1 | sort | uniq -c

这个指令用来将『重复的行删除掉只显示一个』,举个例子来说, 你要知道这个月份登入你主机的使用者有谁,而不在乎他的登入次数,那么就使用上面的范例, (1)先将所有的数据列出;(2)再将人名独立出来;(3)经过排序;(4)只显示一个! 由于这个指令是在将重复的东西减少,所以当然需要『配合排序过的档案』来处理

• wc

如果我想要知道 /etc/man.config 这个档案里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以利用 wc 这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!

[root@linux ~]# wc [-lwm]

参数:

-l :仅列出行;

-w :仅列出多少字(英文单字);

-m :多少字符;

范例:

范例一:那个 /etc/man.config 里面到底有多少相关字、行、字符数?

[root@linux ~]# cat /etc/man.config | wc

138 709 4506

# 输出的三个数字中,分别代表: 『行、字数、字符数』

范例二:我知道使用 last 可以输出登入者,但是 last 最后两行并非账号内容,

那么请问,我该如何以一行指令串取得这个月份登入系统的总人次?

[root@linux ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l

# 由于 last 会输出空白行与 wtmp 字样在最底下两行,因此,我利用

# grep 取出非空白行,以及去除 wtmp 那一行,在计算行数,就能够了解啰

双向重导向: tee

[root@linux ~]# tee [-a] file

参数:

-a :以累加 (append) 的方式,将数据加入 file 当中!

范例:

[root@linux ~]# last | tee last.list | cut -d " " -f1

# 这个范例可以让我们将 last 的输出存一份到 last.list 档案中;

[root@linux ~]# ls -l /home | tee ~/homefile | more

# 这个范例则是将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息!

[root@linux ~]# ls -l / | tee -a ~/homefile | more

# 要注意: tee 后接的档案会被覆盖,所以,我们要加上 -a

# 这个参数才能将讯息累加。

• tr

tr 可以用来删除一段讯息当中的文字,或者是进行文字讯息的替换!

[root@linux ~]# tr [-ds] SET1 ...

参数:

-d :删除讯息当中的 SET1 这个字符串;

-s :取代掉重复的字符!

范例:

范例一:将 last 输出的讯息中,所有的小写变成大写字符:

[root@linux ~]# last | tr '[a-z]' '[A-Z]'

范例二:将 /etc/passwd 输出的讯息中,将冒号 (:) 删除

[root@linux ~]# cat /etc/passwd | tr -d ':'

范例三:将 DOS 档案的断行字符 ^M 符号删除:

[root@linux ~]# cat /home/test/dostxt | tr -d '\r' > dostxt-noM

# 那个 /r 指的是 DOS 的断行字符

• col

[root@linux ~]# col [-x]

参数:

-x :将 tab 键转换成对等的空格键

范例:

[root@linux ~]# cat -A /etc/man.config <==此时会看到很多 ^I 的符号,那就是 tab

[root@linux ~]# cat /etc/man.config | col -x | cat -A | more

# 嘿嘿!如此一来, [tab] 按键会被取代成为空格键,输出就美观多了!

join

join 看字面上的意义 (加入/参加) 就可以知道,他是在处理两个档案之间的数据, 而且,主要是在处理『两个档案当中,有 "相同数据" 的那一行,将他加在一起』的意思。我们利用底下的简单例子来说明:

[root@linux ~]# join [-ti12] file1 file2

参数:

-t :join 预设以空格符分隔数据,并且比对『第一个字段』的数据,

如果两个档案相同,则将两笔数据联成一行,且第一个字段放在第一个!

-i :忽略大小写的差异;

-1 :这个是数字的 1 ,代表『第一个档案要用那个字段来分析』的意思;

-2 :代表『第二个档案要用那个字段来分析』的意思。

范例:

范例一:用 root 的身份,将 /etc/passwd 与 /etc/shadow 相关数据整合成一栏

[root@linux ~]# join -t ':' /etc/passwd /etc/shadow

bin:x:1:1:bin:/bin:/sbin/nologin:*:12959:0:99999:7:::

daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:12959:0:99999:7:::

adm:x:3:4:adm:/var/adm:/sbin/nologin:*:12959:0:99999:7:::

# 因为 /etc/shadow 的权限问题,所以这里必须是 root 才能动作!而 /etc/passwd

# 与 /etc/shadow 都是以 : 来分隔字段,所以必须要使用 -t ':' 规范字段分隔字符。

# 且,因为 /etc/shadow 与 /etc/passwd 刚好都是以第一个字段为账号名称,所以,

# 就可以将同一行的数据给他贴在一起了!

# 另外,再仔细看一下 /etc/shadow 的内容与 /etc/passwd 的内容,您会发现,

# 两者都以账号为开始,而上面的输出数据中您会发现特殊字体部分,那代表

# 第二个档案的内容。在第二个档案的内容部分,由于账号(第一个字段)与

# 第一的档案是相同的,所以当然就省略掉,因此就成为上面的输出。

范例二:我们知道 /etc/passwd 第四个字段是 GID ,那个 GID 记录在

/etc/group 当中的第三个字段,请问如何将两个档案整合?

[root@linux ~]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group

0:root:x:0:root:/root:/bin/bash:root:x:

1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:root,bin,daemon

2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:root,bin,daemon

4:adm:x:3:adm:/var/adm:/sbin/nologin:adm:x:root,adm,daemon

# 这个例子就更明显了!原本的 /etc/passwd 的第一行内容应该是:

# root:x:0:0:root:/root:/bin/bash

# 至于 /etc/group 第一行内容应该是:

# root:x:0:

# 我将第一个档案的第四栏与第二个档案的第三栏取出,放置到输出的最前方,

# 然后将剩下的数据给他加在一起!

paste

paste 就直接『将两行贴在一起,且中间以 [tab] 键隔开』而已!简单的使用方法:

[root@linux ~]# paste [-d] file1 file2

参数:

-d :后面可以接分隔字符。预设是以 [tab] 来分隔的!

- :如果 file 部分写成 - ,表示来自 standard input 的资料的意思。

范例:

范例一:将 /etc/passwd 与 /etc/shadow 同一行贴在一起

[root@linux ~]# paste /etc/passwd /etc/shadow

bin:x:1:1:bin:/bin:/sbin/nologin bin:*:12959:0:99999:7:::

daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:12959:0:99999:7:::

adm:x:3:4:adm:/var/adm:/sbin/nologin adm:*:12959:0:99999:7:::

# 注意喔!同一行中间是以 [tab] 按键隔开的!

范例二:先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行

[root@linux ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3

# 这个例子的重点在那个 - 的使用!那玩意儿常常代表 stdin 喔!

• expand

这玩意儿就是在将 [tab] 按键转成空格键啦:

[root@linux ~]# expand [-t] file

参数:

-t :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。

我们也可以自行定义一个 [tab] 按键代表多少个字符呢!

范例:

范例一:将 /etc/man.config 内行首为 MANPATH 的字样就取出;仅取前三行;

[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3

MANPATH /usr/man

MANPATH /usr/share/man

MANPATH /usr/local/man

# 行首的代表标志为 ^ ,这个我们留待下节介绍!先有概念即可!

范例二:承上,如果我想要将所有的符号都列出来?(用 cat)

[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A

MANPATH^I/usr/man$

MANPATH^I/usr/share/man$

MANPATH^I/usr/local/man$

# 发现差别了吗?没错~ [tab] 按键可以被 cat -A 显示成为 ^I

范例三:承上,我将 [tab] 按键设定成 6 个字符的话?

[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 | \

> expand -t 6 - | cat -A

MANPATH /usr/man$

MANPATH /usr/share/man$

MANPATH /usr/local/man$

123456123456123456.....

# 仔细看一下上面的数字说明,因为我是以 6 个字符来代表一个 [tab] 的长度,所以,

# MAN... 到 /usr 之间会隔 12 (两个 [tab]) 个字符喔!如果 tab 改成 9 的话,

# 情况就又不同了!这里也不好理解~您可以多设定几个数字来查阅就晓得!

expand 也是挺好玩的~他会自动将 [tab] 转成空格键~所以,以上面的例子来说, 使用 cat -A 就会查不到 ^I 的字符啰~此外,因为 [tab] 最大的功能就是格式排列整齐! 我们转成空格键后,这个空格键也会依据我们自己的定义来增加大小~ 所以,并不是一个 ^I 就会换成 8 个空白

分割命令: split

如果你有档案太大,导致一些携带式装置无法复制的问题,找 split 就对了! 他可以帮你将一个大档案,依据档案大小或行数来分割,就可以将大档案分割成为小档案了! 快速又有效啊!

[root@linux ~]# split [-bl] file PREFIX

参数:

-b :后面可接欲分割成的档案大小,可加单位,例如 b, k, m 等;

-l :以行数来进行分割。

范例:

范例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一个档案时?

[root@linux ~]# cd /tmp; split -b 300k /etc/termcap termcap

[root@linux tmp]# ls -l termcap*

-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapaa

-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapab

-rw-rw-r-- 1 root root 184848 8月 17 00:25 termcapac

# 那个档名可以随意取的啦!我们只要写上前导文字,小档案就会以

# xxxaa, xxxab, xxxac 等方式来建立小档案的!

范例二:如何将上面的三个小档案合成一个档案,档名为 termcapback

[root@linux tmp]# cat termcap* >> termcapback

# 很简单吧?就用数据流重导向就好啦!简单!

范例三:使用 ls -al / 输出的信息中,每十行记录成一个档案

[root@linux tmp]# ls -al / | split -l 10 - lsroot

# 重点在那个 - 啦!一般来说,如果需要 stdout/stdin 时,但偏偏又没有档案,

# 有的只是 - 时,那么那个 - 就会被当成 stdin 或 stdout ~

关于减号 - 的用途

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

[root@linux ~]# tar -cvf - /home | tar -xvf -

上面这个例子是说:『我将 /home 里面的档案给他打包,但打包的数据不是纪录到档案,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个指令的 stdout, 因此,我们就不需要使用 file 了!

摘自《鸟哥私房菜》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐