linux学习笔记第二篇之bash

快捷键

  • ^u 向前删除所有; ^k 向后删除所有
  • ^a(ahead)移至最前面,^e(end)移至最后

变量

内置变量例如PATH,HOME,RANDOM

1
2
[dmtsai@study ~]$ declare -i number=$RANDOM*10/32768 ; echo $number
8 <== 此時會隨機取出 0~9 之間的數值喔!
  • 获取环境变量env(所有bash都具有的变量).获取环境变量和自订变量set

  • 将临时变量变为环境变量export var,获取当前的环境变量export

    1
    2
    3
    4
    5
    6
    7
    work=/home/s0me/tmp 
    export work #当前bash和所有的子进程的环境变量,新的bash shell中并不会有此变量
    #只能将某个变量设为子进程和当前进程的环境变量

    bash #打开新的bash子进程
    cd $work #成功的进入了设定好的work目录
    exit #关闭子bash进程

变量取用

$var or ${var}

1
2
echo $HOME  #输出 /home/dream
echo ${HOME} #输出同上

变量设定规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
######变量后的注释行均为执行 echo ${变量} 之后的输出 ######
myn=s0me #正确
#s0me
myname2=s0me2 #正确
#s0me2
var="lang is $LANG" #双引号内特殊字符保留原有特性
#lang is zh_CN.UTF-8
var2='lang is $LANG' #单引号全为一般字符
#lang is $LANG
myname3=s0me\ meng #正确 \ 可将特殊字符[enter],[$],[\],[space],[']变为一般字符
#s0me meng
version=$(uname -r) #一串指令调用其他指令,可以用[`指令`]或者[$(指令)]
#4.15.0-44-generic
myname4=${myn}12 #扩增变量内容,直接在[${指令}]或者["$指令"]后连接即可
#s0me12
myname5=${myn}:123\;"$myn"233\;"${myn}"2333 #连接变量内容
#s0me:123;s0me233;s0me2333
  • =连接,且等号两侧无空白字符
  • 变量中有空白字符,可用引号将变数内容结合起来
    • "双引号保留特殊字符原有特性
    • '单引号全为一般字符
  • \转义功能,注意可将[sapce]转义, 即 var=i\ am\ foo是合法语句
  • 一串指令调用其他指令,可以用 [`指令`] 或者[$(指令)] 优先调用
  • 扩增变量内容,直接在[${指令}] 或者[" $指令"]后连接即可
  • 特别注意: 反单引号,$(指令)(小括号)只能包含指令;${变量}(中括号)只能包含变量
  • 若该变量需要在其他子程序执行,则需要以export来使变量变成环境变量export var
  • 取消变量unset

一些常用变量

  1. PS1 命令提示字元,即s0me@s0me-Laptop:~$
    • \d:可显示出『星期月日』的日期格式,如:"Mon Feb 2"
    • \H:完整的主机名称。举例来说,鸟哥的练习机为『study.centos.vbird』
    • \h :仅取主机名称在第一个小数点之前的名字,如鸟哥主机则为『study』后面省略
    • \t :显示时间,为24 小时格式的『HH:MM:SS』
    • \T:显示时间,为12 小时格式的『HH:MM:SS』
    • \A :显示时间,为24 小时格式的『HH:MM』
    • \@ :显示时间,为12 小时格式的『am/pm』样式
    • \u:目前使用者的帐号名称,如『dmtsai』;
    • \v:BASH 的版本资讯,如鸟哥的测试主机版本为4.2.46(1)-release,仅取『4.2』显示
    • \w:完整的工作目录名称,由根目录写起的目录名称。但家目录会以~ 取代;
    • \W:利用basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
    • \#:下达的第几个指令。
    • \$ :提示字元,如果是root 时,提示字元为# ,否则就是$ 啰~
1
2
3
4
5
6
7
8
9
#example 01
[dmtsai@study ~]$ cd /home
[dmtsai@study home]$ PS1='[\u@\h \w \A #\#]\$ '
[dmtsai@study /home 17:02 #85]$

#example 02
s0me@s0me-laptop:~$ PS1='[Path:\w][\#]\$'
[Path:~][2]$
#注意修改时用单引号,避免提前转义
  1. $ 目前shell的进程号.

    echo $$,会返回目前shell的 pid

  2. ?上一条指令的传回值 echo $?为0,表示上一条指令执行成功,不为0,表示执行错误

设定语系

  • locale -a 显示当前支持的所有语言

  • locale 显示当前语言相关的环境变量,一般修改LANG即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [dmtsai@study ~]$ locale   <==后面不加任何选项与参数即可!
    LANG=en_US <==主语言的环境
    LC_CTYPE="en_US" <==字元(文字)辨识的编码
    LC_NUMERIC="en_US" <==数字系统的显示讯息
    LC_TIME="en_US" <==时间系统的显示资料
    LC_COLLATE="en_US" <==字串的比较与排序等
    LC_MONETARY="en_US" <==币值格式的显示等
    LC_MESSAGES="en_US" <==讯息显示的内容,如功能表、错误讯息等
    LC_ALL= <==整体语系的环境

  • 如果不生效可用export进行一下转换

读取键盘输入

命令 read

1
2
3
4
5
6
7
8
$ read [-pt] var
# 选项与参数:
# -p :后面可以接提示字元!
# -t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!
$ read -p "your name?" -t 4 name
your name?ljmeng
$ echo ${name}
ljmeng

变量类型声明

命令declare

变量类型预设为字符串

1
2
3
4
5
6
$ declare [-aixr] variable 
# 选项与参数:
# -a :将后面名为variable 的变数定义成为阵列(array) 类型
# -i :将后面名为variable 的变数定义成为整数数字(integer) 类型
# -x :用法与export 一样,就是将后面的variable 变成环境变数;
# -r :将变数设定成为readonly 类型,该变数不可被更改内容,也不能unset

数组(array)变量类型

设定方法 var[index]=content , \(index \in [0, +\infin)\).

限制可用资源

命令 ulimit [-SHacdfltu] [配额]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[dmtsai@study ~]$ ulimit [-SHacdfltu] [配额]  
# 选项与参数:
# -H :hard limit ,严格的设定,必定不能超过这个设定的数值;
# -S :soft limit ,警告的设定,可以超过这个设定值,但是若超过则有警告讯息。
# 在设定上,通常soft 会比hard 小,举例来说,soft 可设定为80 而hard
# 设定为100,那么你可以使用到90 (因为没有超过100),但介于80~100 之间时,
# 系统会有警告讯息通知你!
# -a :后面不接任何选项与参数,可列出所有的限制额度;
# -c :当某些程式发生错误时,系统可能会将该程式在记忆体中的资讯写成档案(除错用),
# 这种档案就被称为核心档案(core file)。此为限制每个核心档案的最大容量。
# -f :此shell 可以建立的最大档案容量(一般可能设定为2GB)单位为Kbytes
# -d :程序可使用的最大断裂记忆体(segment)容量;
# -l :可用于锁定(lock) 的记忆体量
# -t :可使用的最大CPU 时间(单位为秒)
# -u :单一使用者可以使用的最大程序(process)数量。

变量内容的删除,取代与替换(optimal)

删除与取代

注意删除内容一定从某一端开始并包含某一端,不能单独删除中间一段

  • # 从开始删除 第一个 最短符合通配符的
  • ## 从开始删除 第一个 最长符合通配符的
  • % 从结尾开始 第一个 最短符合通配符的
  • %% 从结尾开始 第一个 最长符合通配符的
1
2
3
4
5
6
7
8
9
10
11
12
s0me@s0mE-laptop:~$ echo ${PATH}
# /usr/local/sbin:/usr/local/bin:/bin:/usr/games:/usr/local/games:/snap/bin
s0me@s0mE-laptop:~$ echo ${PATH#/*:}
# /usr/local/bin:/bin:/usr/games:/usr/local/games:/snap/bin
s0me@s0mE-laptop:~$ echo ${PATH##/*:}
# /snap/bin
s0me@s0mE-laptop:~$ echo ${PATH%/*bin}
# /usr/local/sbin:/usr/local/bin:/bin:/usr/games:/usr/local/games:/snap
s0me@s0mE-laptop:~$ echo ${PATH%%/*bin}
# <==注意这里输出为空
s0me@s0mE-laptop:~$ echo ${PATH%%/*:} #为无效命令,因为不包含右端
# /usr/local/sbin:/usr/local/bin:/bin:/usr/games:/usr/local/games:/snap/bin
  • ${var/old_str/new_str} 替换第一个符合旧字串的字符串
  • ${var//old_str/new_str} 替换全部符合旧字串的字符串

变量的测试与内容替换

  • 判断变量是否存在(即是否初始化过)或者是否为空字符串
变数设定方式 str 没有设定 str 为空字串 str 已设定非为空字串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr} str=expr var=expr str不变 var= str不变 var=$str
var=${str:=expr} str=expr var=expr str=expr var=expr str不变 var=$str
var=${str?expr} expr 输出至stderr var= var=$str
var=${str:?expr} expr 输出至stderr expr 输出至stderr var=$str

命令别名与历史命令

  1. 命令别名alias,unalias
  2. 历史命令history, history 5可以查询最近五次的命令
  3. !n执行第n次命令
  4. !!执行上一次命令
  5. !al 执行最近的以al开头的那个指令

Shell 的操作环境

路径与指令搜索顺序

  1. 相对路径
  2. alias寻找
  3. bash内置指令寻找
  4. 通过$PATH变量查找

bash的进站与欢迎讯息

  1. 终端进站提示信息cat /etc/issue

    • 内部代码含义

      1
      2
      3
      4
      5
      6
      7
      8
      9
      \d本地端时间的日期;
      \l显示第几个终端机介面;
      \m显示硬体的等(i386/i486/i586/i686...);
      \n显示主机的网路名称;
      \O显示domain name;
      \r作业系统的版本(相当于uname -r)
      \t显示本地端时间的时间;
      \S作业系统的名称;
      \v作业系统的版本。

  2. /etc/issue.net 提供给telnet连接

  3. /etc/motd你编写的给所有登陆者的信息

bash的环境设定档

login 与 non-login shell

login shell

1.etc/profile包含环境变量,呼叫如下文档:

1
2
3
/etc/profile.d/*.sh #包含命令别名
/etc/locale.conf #语系设定
/usr/share/bash-completion/completions/* #命令tab自动补全处理

2.~/.bash_profile or~/.bash_login or ~/.profile,包含用户个人设定,会呼叫~/.bashrc

non-login shell

只会读取~/.bashrc

source 命令

source xxx or . xxx, 读入文档xxx的设定, 无需重启系统,即可使自己的修改生效

其他设定文档

1
2
3
/etc/man_db.conf # man page 查找路径
~/.bash_history #历史命令
~/.bash_logout # bash登出时运行的命令

终端机(tty)的环境设定: stty, set

stty

1
2
3
4
5
6
7
8
9
10
$ stty [-a] 
# 选项与参数:
# -a :将目前所有的stty 参数列出来;

# 列出所有按键与按键内容
$ stty -a
speed 38400 baud; rows 20; columns 90; line = 0;
intr = ^C ; quit = ^\; erase = ^? ; kill = ^U; eof = ^D ; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q ; stop = ^S ; susp = ^Z ; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 1; time = 0;

常用按键对照表如下

变量 快捷键 含义
intr 【ctrl+c】【^c】 发送一个interrupt (中断) 的讯号给目前正在run的程序
quit 【ctrl+】【^】 发送一个quit 的讯号给目前正在run的程序
erase 【ctrl+?】【^?】【backsapce键】 删除字符(删除键用^?表示,很有意思)
kill 【ctrl+u】【^u】 删除在目前指令列上光标前的所有文字
eof 【ctrl+d】【^d】 End of file 的意思,代表『结束输入』
start 【ctrl+q】【^q】 在某个程序停止后,重新启动他的output
stop 【ctrl+s】【^s】 停止目前屏幕的输出(程序仍然在运行)
susp 【ctrl+z】【^z】 送出一个terminal stop(终端停止)的讯号给正在run的程序

修改设定方法

1
$ stty erase ^h   #这个设定看看就好,不必真的实做!不然还要改回来!

set

-启用相应设定,+取消相应设定

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
$ set [-uvCHhmBx] 
# 选项与参数:
# -u :预设不启用。若启用后,当使用未设定变数时,会显示错误讯息;
# -v :预设不启用。若启用后,在讯息被输出前,会先显示讯息的原始内容;
# -x :预设不启用。若启用后,在指令被执行前,会显示指令内容(前面有++ 符号)
# -h :预设启用。与历史命令有关;
# -H :预设启用。与历史命令有关;
# -m :预设启用。与工作管理有关;
# -B :预设启用。与刮号[] 的作用有关;
# -C :预设不启用。若使用> 等,则若档案存在时,该档案不会被覆盖。

# 范例一:显示目前所有的set设定值
$ echo $-
# himBH
# 那个$- 变数内容就是set 的所有设定啦!bash 预设是himBH 喔!

范例二:设定"若使用未定义变数时,则显示错误讯息"
$ set -u
$ echo $vbirding
# -bash: vbirding: unbound variable
# 预设情况下,未设定/未宣告的变数都会是『空的』,不过,若设定-u 参数,
# 那么当使用未设定的变数时,就会有问题啦!很多的shell 都预设启用-u 参数。
# 若要取消这个参数,输入set +u 即可!

# 范例三:执行前,显示该指令内容。
$ set -x
# ++ printf '\033]0;%s@%s:%s\007' dmtsai study '~' #这个是在列出提示字元的控制码!
$ echo ${HOME}
# + echo /home/dmtsai
# /home/dmtsai
# ++ printf '\033]0;%s@%s:%s\007' dmtsai study '~'
# 看见否?要输出的指令都会先被列印到萤幕上喔!前面会多出+ 的符号!

万用字符和特殊符号

万用字符

符号 意义
* 『 0 个到无穷多个』任意字元
? 『一定有一个』任意字元
[ ] 『一定有一个在括号内』的字元(非任意字元)。[abcd] 代表『一定有一个字元,可能是a, b, c, d 这四个任何一个』
[ - ] 若有减号在中括号内时,代表『在编码顺序内的所有字元』。例如[0-9] 代表 0 到9 之间的所有数字
[^ ] 若中括号内的第一个字元为指数符号(^) ,那表示『反向选择』,例如·[^abc] 代表一定有一个字元,只要是非a, b, c 的其他字元就接受的意思。

特殊符号

符号 内容
# 注解符号:这个最常被使用在script 当中,视为说明!在后的资料均不执行
\ 跳脱符号:将『特殊字元或万用字元』还原成一般字元
| 管线(pipe):分隔两个管线命令的界定(后两节介绍);
; 连续指令下达分隔符号:连续性命令的界定(注意!与管线命令并不相同)
~ 使用者的家目录
$ 取用变数前置字元:亦即是变数之前需要加的变数取代值
& 工作控制(job control):将指令变成背景下工作
! 逻辑运算意义上的『非』 not 的意思!
/ 目录符号:路径分隔的符号
>, >> 资料流重导向:输出导向,分别是『取代』与『累加』
<, << 资料流重导向:输入导向(这两个留待下节介绍)
' ' 单引号,不具有变数置换的功能($ 变为纯文字)
" " 具有变数置换的功能!($ 可保留相关功能)
` ` 两个『 ` 』中间为可以先执行的指令,亦可使用$( )
( ) 在中间为子shell 的起始与结束
{ } 在中间为命令区块的组合!

数据流重定向

重定向简介

三种数据流 stdout, stdin, stderr

指令执行过程的资料传输情况
类型 代码 符号
标准输入(stdin) 0 < 或<<
标准输出(stdout) 1 > 或>>; 1>或1>>也可
标准错误输出(stderr) 2 2> 或2>>

单个>表示以覆盖方式输出,两个>>表示以追加的方式输出

单个<表示以后面的文件为标准输入,两个<<后面表示自己定义的输入结束标志符

1
2
3
4
5
6
7
8
9
10

# 范例二:利用一般身份帐号搜寻/home底下是否有名为.bashrc的档案存在
$ find /home -name .bashrc <==身份是dmtsai喔!
# find: '/home/arod': Permission denied <== Standard error output
# find: '/home/alex': Permission denied <== Standard error output
# /home/dmtsai/.bashrc <== Standard output

# 范例三:承范例二,将stdout与stderr分存到不同的档案去
$ find /home -name .bashrc > list_right 2> list_error
#此时屏幕中无任何信息,输出全部 重定向到了相应文件中

dev/null垃圾桶黑洞

1
2
3
# 范例四:承范例三,将错误的资料丢弃,萤幕上显示正确的资料 
$ find /home -name .bashrc 2> /dev/null
# /home/dmtsai/.bashrc <==只有stdout会显示到萤幕上, stderr被丢弃了

将正确与错误输出写入同一个文件

2>&1将2号输出流重定向至1号输出流, 1>&2同理

1
2
3
4
5

# 范例五:将指令的资料全部写入名为list的档案中
$ find /home -name .bashrc > list 2> list # <==错误
$ find /home - name .bashrc > list 2>&1 # <==正确
$ find /home -name .bashrc &> list # <==正确

stdin < 与 <<

cat 创建文档 cat > catfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 利用cat指令来建立一个档案的简单流程 
$ cat > catfile
testing
cat file test
# <==这里按下[ctrl]+d来离开

# 用stdin取代键盘的输入以建立新档案的简单流程
$ cat > catfile < ~/.bashrc

# 用关键字结束输入而不是^d
$ cat > catfile << "eof"
> This is a test.
> OK now stop
> eof # <==输入这关键字,立刻就结束而不需要输入[ctrl]+d,文件最终不包含“eof”

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

cmd ; cmd

不考虑指令相关性的连续指令下达

$? (指令回传值) 与&& 或||

单独指令含义如下

指令下达情况 说明
cmd1 && cmd2 cmd1执行完毕后, 若正确执行($? == 0),则执行cmd2。否则不执行。
cmd1 || cmd2 cmd1执行完毕后, 若未正确执行($? != 0),则cmd2执行。 否则不执行。

不同的连接顺序含义不同

指令 含义
cmd1 && cmd2 || cmd3 如果cmd1正确运行则执行cmd2,否则执行cmd3
cmd1 || cmd2 && cmd3 如果cmd1错误运行则执行cmd2,并执行cmd3,否则执行cmd3

ps: 以上前提是cmd2,cmd3一旦执行都能正常运行

管线命令(pipe)

一般仅能处理stdout, 会忽略stderr,不过可以通过2>&1处理stderr

撷取命令: cut, grep

cut

分解同一行的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cut -d '分隔字元' -f fields # <==用于有特定分隔字元 
$ cut -c 字元区间 # <==用于排列整齐的讯息
# 选项与参数:
# -d :后面接分隔字元。与-f 一起使用;
# -f :依据-d 的分隔字元将一段讯息分割成为数段,用-f 取出第几段的意思;
# -c :以字元(characters) 的单位取出固定字元区间;

dream@dream-Laptop:~$ echo ${PATH}
# /home/dream/miniconda3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
dream@dream-Laptop:~$ echo ${PATH} | cut -d ":" -f 1,4,5-7
# /home/dream/miniconda3/bin:/usr/sbin:/usr/bin:/sbin:/bin
dream@dream-Laptop:~$ echo ${PATH} | cut -c 1,4,5-7
# /me/d

grep

分析一行信息,如果包含我们想要的信息,则取出该行。

1
2
3
4
5
6
7
8
$ grep [-acinv] [--color=auto] '搜寻字串' filename 
# 选项与参数:
# -a :将binary 档案以text 档案的方式搜寻资料
# -c :计算找到'搜寻字串' 的次数(行数)
# -i :忽略大小写的不同,所以大小写视为相同
# -n :顺便输出行号
# -v :反向选择,亦即显示出没有'搜寻字串' 内容的那一行!
# --color=auto :可以将找到的关键字部分加上颜色的显示喔!

排序命令:sort, wc, uniq

sort

1
2
3
4
5
6
7
8
9
10
11
$ sort [-fbMnrtuk] [file or stdin] 
# 选项与参数:
# -f :忽略大小写的差异,例如A 与a 视为编码相同;
# -b :忽略最前面的空白字元部分;
# -M :以月份的名字来排序,例如JAN, DEC 等等的排序方法;
# -n :使用『纯数字』进行排序(预设是以文字型态来排序的);
# -r :反向排序;
# -u :就是uniq ,相同的资料中,仅出现一行代表;
# -t :分隔符号,预设是用[tab] 键来分隔;
# -k :以那个区间(field) 来进行排序的意思

uniq

重复的资料仅列出一个显示

1
2
3
4
5
6
7
$ uniq [-ic]
# 选项与参数:
# -i :忽略大小写字元的不同;
# -c :进行计数

#last将帐号列出,仅取出帐号栏,进行排序后仅取出一位
$last | cut -d ' ' -f1 | sort | uniq -c

wc

1
2
3
4
5
6
$ wc [-lwm] 
# 选项与参数:
# 默认列出 『行、字数、字元数』
# -l :仅列出行;
# -w :仅列出多少字(英文单字);
# -m :多少字元;

双向重导向 tee

tee 的工作流程示意图

tee功能如图所示,tee输出到screen其实就是 stdout.

1
2
3
4
5
$ tee [-a] file
# -a : 以append的方式加入到资料file中

$ last | tee last.list | cut -d " " -f1
# 导出到last.list并且下一步还有处理并最终会输出到屏幕上

字元转换命令 tr, col, join, paste, expand

tr

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

1
2
3
4
5
6
7
$ tr [-ds] SET1 ... 
# 选项与参数:
# -d :删除讯息当中的SET1 这个字串;
# -s :取代掉重复的字元!

# 将last输出的讯息中,所有的小写变成大写字元
$ last | tr '[a-z]' '[A-Z]'

col

将[tab] 按键取代成为空白键

1
2
3
4
5
6
7
$ col [-xb] 
# 选项与参数:
# -x :将tab 键转换成对等的空白键

# 利用cat -A显示出所有特殊按键,最后以col将[tab]转成空白
$ cat -A /etc/man_db.conf # <==此时会看到很多^I的符号,那就是tab
$ cat /etc/man_db.conf | col -x | cat -A | more

join

对比两个档案,将有"相同资料" 的行对应合并为一行,注意先排序,否则会少合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ join [-ti12] file1 file2 
# 选项与参数:
# -t :join 预设以空白字元分隔资料,并且比对『第一个栏位』的资料,
# 如果两个档案相同,则将两笔资料联成一行,且第一个栏位放在第一个!
# -i :忽略大小写的差异;
# -1 :这个是数字的1 ,代表『第一个档案要用那个栏位来分析』的意思;
# -2 :代表『第二个档案要用那个栏位来分析』的意思。

#例子如下
$ join -t ':' -1 4 /etc/passwd -2 3 /etc/group 2>/dev/null | head -n 3
# 0:root:x:0:root:/root:/bin/bash:root:x:
# 1:daemon:x:1:daemon:/usr/sbin:/usr/sbin/nologin:daemon:x:
# 2:bin:x:2:bin:/bin:/usr/sbin/nologin:bin:x:
$ head -n 3 /etc/passwd /etc/group
# ==> /etc/passwd <==
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# bin:x:2:2:bin:/bin:/usr/sbin/nologin
#
# ==> /etc/group <==
# root:x:0:
# daemon:x:1:
# bin:x:2:

paste

将两行贴在一起,且中间以[tab]键隔开

1
2
3
4
$ paste [-d] file1 file2 
# 选项与参数:
# -d :后面可以接分隔字元。预设是以[tab] 来分隔的!
# - :如果file 部分写成- ,表示来自standard input 的资料的意思。

expand

将[tab] 按键转成空白键

1
2
3
4
$ expand [-t] file 
# 选项与参数:
# -t :后面可以接数字。一般来说,一个tab 按键可以用8 个空白键取代。
# 我们也可以自行定义一个[tab] 按键代表多少个字元呢!

分割命令:split

将大档案分割成小档案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ split [-bl] file PREFIX 
# 选项与参数:
# -b :后面可接欲分割成的档案大小,可加单位,例如b, k, m 等;
# -l :以行数来进行分割。
# PREFIX :代表前置字元的意思,可作为分割档案的前导文字。

# 分解例子
$ split -l 1 welcome.txt part
$ ll
# 总用量 695
# ...
# -rwxrwxrwx 1 root root 1 3月 9 19:02 partaa*
# -rwxrwxrwx 1 root root 11 3月 9 19:02 partab*
# -rwxrwxrwx 1 root root 27 3月 9 19:02 partac*
# -rwxrwxrwx 1 root root 33 3月 9 19:02 partad*
# ...
# -rwxrwxrwx 1 root root 72 1月 31 13:06 welcome.txt*

# 合并方法
$ cat part* >> welcomeback

参数代换:xargs

产生某个指令的参数,xargs可以读入stdin的资料,并且以空白字元或断行字元作为分辨,将stdin的资料分隔成为arguments 。

很多指令其实并不支援管线命令,因此我们可以透过xargs来提供该指令引用standard input之用

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
$ xargs [-0epn] command 
# 选项与参数:
# -0 :如果输入的stdin 含有特殊字元,例如`, \, 空白键等等字元时,这个-0 参数
# 可以将他还原成一般字元。这个参数可以用于特殊状态喔!
# -e :这个是EOF (end of file) 的意思。后面可以接一个字串,当xargs 分析到这个字串时,
# 就会停止继续工作!
# -p :在执行每个指令的argument 时,都会询问使用者的意思;
# -n :后面接次数,每次command 指令执行时,要使用几个参数的意思。
# 当xargs 后面没有接任何的指令时,预设是以echo 来进行输出喔!

$ 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时,都要询问使用者是否动作?
$ 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就结束指令串
$ cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
#仔细与上面的案例做比较。也同时注意,那个-e'sync'是连在一起的,中间没有空白键。
# 上个例子当中,第六个参数是sync 啊,那么我们下达-e'sync' 后,则分析到sync 这个字串时,
# 后面的其他stdin 的内容就会被xargs 舍弃掉了!

关于减号 - 的用途

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

1
2
$ mkdir /tmp/homeback 
$ tar -cvf - /home | tar -xvf - -C /tmp/homeback

减号相当于stdin,stdout的跳转管道