只要能操作应用程序的接口都可称为shell。可以是图形接口,也可以是文字接口。
操作系统合法的shell均写在 /etc/shells 文件中。
用户默认登录取得的shell记录于 /etc/passwd 的最后一个字段。
bash进系统欢迎信息
直接登录系统:/etc/issue
远程登录系统:/etc/issue.net
全部设定登录:/etc/motd
issue中各字符含义
代码 | 意义 |
\d | 显示本地时间的日期 |
\l | 显示第几个终端接口 |
\m | 显示硬件的等级(i386/i486/i586/i786...) |
\n | 显示主机的网络名称 |
\O | 显示域名domain name |
\r | 显示操作系统版本;同 uname -r |
\t | 显示本地时间的时间 |
\S | 显示操作系统名称 |
\v | 显示操作系统版本 |
bash环境配置文件
login shell:获取bash时需要完整登入流程的,比如从tty1~6登入系统输入账号密码,就为 login shell
non-login shell:无需重复登入流程的,比如在系统内部启动tty1~6,不用输入账号密码,就为 non-login shell
login shell读取文件顺序:
一:首先一定会读取的 /etc/profile(整体环境配置)
二:接着读取使用者个人配置文件 【1】~/.bash_profile 【2】 ~/.bash_login【3】 ~/.profile login shell只会读取三个文件中一个,读取顺序依次,若有一个存在,则后续的不再读取。
non-login shell仅读取 ~/.bashrc
历史命令-history
默认的命令记录条数可以到达1000个。记录存在于家目录的 .bash_history ,此文件记录的是前一次登录所执行过的命令,此次登录所执行的命令都被缓存在内存中,当成功注销系统后,此次命令才会记录到 ./bash_history 中
history [参数] historyfiles
n:数字,列出多少行
-c:将目前shell中所有的history内容全部消除
-a:将目前新增的history指令增入historyfiles中,若没写historyfiles,则默认写入 ~/.bash_history
-r:将history文件内容读到整个shell中的history记忆中
-w:将目前history记忆内容写入historyfiles中
同一账号同时多次登录时,最后一个注销的bash是最后写入的数据;
可与以下命令搭配使用
!number:执行第几个命令
!command:由最近的命令向前搜寻以command开头的命令并执行该命令
!!:执行上一个命令
[root@wzy ~]#who am i
root pts/0 2023-04-25 03:04 (192.168.29.1)
[root@wzy ~]#echo zhangsan
zhangsan
[root@wzy ~]#echo lisi
lisi
[root@wzy ~]#history
822 who am i
823 echo zhangsan824 echo lisi
825 history
[root@wzy ~]#!823
echo zhangsan
zhangsan
[root@wzy ~]#!!
echo zhangsan
zhangsan[root@wzy ~]#!who
who am i
root pts/0 2023-04-25 03:04 (192.168.29.1)
命令与文件补全-【Tab】键
【Tab】接在一串命令的第一个字后面,则为命令补全。
【Tab】接在一串命令的第二个字后面,则为文件补齐。
命令别名设置功能-alias
alias 新命令 = ‘旧命令 选项’
比如:alias lm = ‘ls -la’
取消alias 使用 unalias 新命令,比如 unalias lm
type:查询命令是否为bash shell 内置命令
type [-tpa] name
不加任何选项和参数时,会显示name是外部指令还是bash内建指令
-t:将name以不同的关键字代表其类别。file为外部指令;alias为别名;builtin为bash内建指令
-p:当name为外部指令时,显示完整文件名
-a:由PATH变量定义的路径中,将所有含name的指令都列出来,包括alias
内部命令:使用 type
命令时,如果返回结果为 "是别名"(aliased to)或 "是内置命令"(is a shell builtin),则该命令是内部命令。
外部命令:如果 type
命令返回命令的路径,如 "是哈希"(hashed)或直接显示命令的完整路径,那么该命令是外部命令。
PS1:提示字符的的设定
- \d:可显示【星期 月 日】的日期格式
- \H:完整的主机名
- \h:仅去主机名在第一个小数点之前的名字
- \t:显示时间,24小时格式的【HH:MM:SS】
- \T:显示时间,12小时格式的【HH:MM:SS】
- \A:显示时间,24小时格式的【HH:MM】
- \@:显示时间,12小时格式的【am/pm】
- \u:目前使用者的账号名
- \v:bash的版本信息
- \w:完整的工作目录名称,由根目录写起,但家目录会以 ~ 代替
- \W:利用 basename 函数取得工作目录名称,所以仅列出最后一个目录名
- \#:下达的第几个指令
- \$:提示字符,root显示 # ,否则显示 $
$:当前shell的线程代号
echo $$ 出现的数字即当前PID号码
locale
/etc/locale.conf 影响显示结果的语系变量;
其中最重要的两个变量 LANG 或 LC_ALL ,这两个设定后其他语系变量会被这两个替代。
read:读取键盘输入
read [-pt] 变量
-p:后面接提示的用户的字符
-t:后面接等待的秒数,时间到后结束等待。
#提示用户5秒内输入名字,用变量 name 接收
[root@wzy ~]#read -p "5秒内输出名字:" -t 5 name
5秒内输出名字:haha
[root@wzy ~]#echo $name
haha
路径与命令搜寻顺序
输入ls命令,命令搜寻顺序为
- 以相对/绝对路径执行命令,例如 /bin/ls 或 ./ls
- 由alias找到该命令来执行
- 由bash内建builtin命令来执行
- 通过$PATH变量的顺序搜寻的第一个命令来执行
变量
变量表示命名的内存空间将数据放在内存空间中,通过变量名引用,获取数据
根据范围划分
普通变量:生效范围为当前shell进程
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片段,通常是函数
赋值
- 直接字符串:name='root'
- 变量引用:name="$USER"
- 命令引用:name=`COMMAND`
变量赋值是临时生效,当退出终端后,变量自动删除,无法持久保存,脚本中的变量会随着脚本结束而自动删除
引用
$name 或 ${name};建议 ${变量名}
变量设定规则:
- 变量与变量内容以一个等号 = 来连接
- 等号两边不能直接接空格符
- 变量名称只能是英文字母、数字和下划线,但开头字符不能是数字
- 不能使用系统中关键字,如if、for、USER等
- 变量内容若有空格符可用双引号或单引号将变量内容括住;但是 双引号 内字符可保持原有特性,单引号 内字符全部视为纯文本;
- 可用跳脱字符反斜杠 \ 将特殊符号(【enter】/【空格】/$/’ )等变成纯文本
- 一串指令借用其他额外指令提供的信息时,可用反单引号 `指令` 或 $(指令)
- 若该变量为扩增变量内容时,可用 “$变量名称” 或 ${变量} 累加内容
- 若该变量需在其他子程序执行,则要以 export 变量 来使变量成环境变量
- 通常大写字符为系统默认变量,自行设定的变量可以用小写字符
- 大驼峰StudentFirstName,小驼峰studentFirstName,下划线student_name
- 见名知义,用英文单词命名并体现实际作用
取消变量
unset 变量
变量数据类型
- 字符 变量类型默认为字符串;
- 数值:整型 bash 环境中的数值运算,预设仅能达到整数形态,如1/3为0;
位置变量
命令:. /test.sh opt1 opt2 opt3 opt4
位置变量: $0 $1 $2 $3 $4
$1、$2等对应第一个、第二个参数。
shift 数字:移动位置变量变量,后面不加数字,默认为1。
[root@centos8 data]# cat shift.sh
#!/bin/bash
echo "first=$1 second=$2 third=$3"
shift
echo "first=$1 second=$2 third=$3"[root@centos8 data]# bash shift.sh 1 2 3
first=1 second=2 third=3
first=2 second=3 third=
$0:命令本身,包括路径
$#:代表除了$0以外,后面接的参数个数,如上即 $# 为4
$@:代表除了$0以外,所有的参数,如上即 “opt1“ “opt2“ “opt3“ “opt4“,每个变量是独立的,每个变量都用双引号括起来
$*:代表除了$0以外,所有的参数,如上即 “opt1 opt2 opt3 opt4“,每个变量之间用空格分割,共用一个双引号
清空所有位置变量
set --
环境变量
env:查看环境变量
[root@wzy ~]#env
#颜色显示设定
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.m4a=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.oga=01;36:*.opus=01;36:*.spx=01;36:*.xspf=01;36:
#发起SSH连接的客户端IP、端口、服务端IP、端口
SSH_CONNECTION=192.168.29.1 14638 192.168.29.141 22
#语系设定
LANG=en_US.UTF-8
#对历史命令去重
HISTCONTROL=ignoredups
#设定将图形显示到何处
DISPLAY=localhost:10.0
#这部主机的主机名
HOSTNAME=wzy.localdomain
#
XDG_SESSION_ID=1
#使用者名称
USER=root
#当前用户所在的工作目录
PWD=/root
#当前用户家目录
HOME=/root
#发起SSH连接的客户端IP、端口、服务端端口
SSH_CLIENT=192.168.29.1 14638 22
#
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
#SSH使用的终端
SSH_TTY=/dev/pts/0
#
MAIL=/var/spool/mail/root
#此终端使用的环境是哪种类型
TERM=xterm
#当前环境下使用的shell
SHELL=/bin/bash
#
SHLVL=1
#
LOGNAME=root
#
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
#
XDG_RUNTIME_DIR=/run/user/0
#环境变量,若有不想加路径执行的命令,把命令路径添加到PATH即可
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#设定history记录的命令数
HISTSIZE=1000
#
LESSOPEN=||/usr/bin/lesspipe.sh %s
#上次使用的命令的最后一个参数或命令本身
_=/usr/bin/env
set:观察所有变量(含环境变量和自定义变量)
export:可使自定义变量转成环境变量
export 变量名称
环境变量可被子进程继续引用
查看指定进程的环境变量
cat /proc/$PID/environ
直接声明环境变量
export name=value 或 declare -x name=value
declare:可使环境变量转成自定义变量
declare +x 变量名称
自定义变量不会被子进程继续引用
declare [-aixr] 变量
-a:将变量类型设定为数组
-A:将变量类型设定为关联数组
-i:将变量类型设定为整数
-x:将变量设定为环境变量,+x 可将环境变量转为自定义变量
-r:将变量设定为 readonly 类型,该变量不可被更改内容,也不能unset
只读变量
只读变量,只能声明定义,后续无法修改删除,即常量
定义只读变量
readonly 变量名
declare -r 变量名
查看只读变量
readonly [-p]
declare -r
退出状态码变量
进程执行后使用 $? 保存状态码相关数字。
执行命令成功返回0;执行命令失败返回其他数字。范围0-255
注意
- 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
- 如果exit后面无数字,终止退出状态取决于exit命令前面的执行结果
- 如果没有exit命令,即未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
变量中字符串的处理
基于偏移量取字符串
返回字符串变量var的字符的长度,一个汉字算一个字符
${#var}返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
${var:offset}返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分
${var:offset:number}取字符串的最右侧几个字符,取字符串的最右侧几个字符, 注意:冒号后必须有一空白字符
${var: -length}从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容,即:掐头去尾
${var:offset:-length}先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格,并且length必须大于offset
${var: -length:-offset}
[root@centos8 data]#name="abcdefghijklmn"
[root@centos8 data]#echo ${#name}
14
[root@centos8 data]#echo ${name:3}
defghijklmn
[root@centos8 data]#echo ${name:3:2}
de
[root@centos8 data]#echo ${name: -4}
klmn
[root@centos8 data]#echo ${name:4:-5}
efghi
[root@centos8 data]#echo ${name: -5:-3}
jk
基于模式取子串
word是指定的任意字符,自左而右,查找var变量所存储的字符串中:
懒惰模式,删除字符串开头至第一次出现word字符串(含)之间的所有字符,以第一个word为界删左留右
${var#*word}贪婪模式,删除的是字符串开头至最后一次出现word字符之间的所有内容,以最后一个word为界删左留右
${var##*word}
[root@centos8 data]#file="var/log/message"
[root@centos8 data]#echo ${file#*/}
log/message
[root@centos8 data]#echo ${file##*/}
message
word是指定的任意字符,自右而左,查找var变量所存储的字符串中:
懒惰模式,删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符,即以从右向左的第一个word为界,删右留左
${var%word*}
贪婪模式,删除字符串最后一个字符向左至最后一次出现word字符之间的所有字符,以从右向左的最后一个word为界,删右留左
${var%%word*}
${var%%word}
[root@centos8 data]#url="http://wenzi.com:8080"
[root@centos8 data]#echo ${url%:*}
http://wenzi.com
[root@centos8 data]#echo ${url%%:*}
http
查找并替换
查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之,懒惰模式
${var/pattern/substr}查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之,贪婪模式
${var//pattern/substr}查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之
${var/#pattern/substr}查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之
${var/%pattern/substr}
查找并删除
删除var表示的字符串中第一次被pattern匹配到的字符串,懒惰模式
${var/pattern}删除var表示的字符串中所有被pattern匹配到的字符串,贪婪模式
${var//pattern}删除var表示的字符串中所有以pattern为行首匹配到的字符串
${var/#pattern}删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
${var/%pattern}
字符大小写转换
把var中的所有小写字母转换为大写
${var^^}把var中的所有大写字母转换为小写
${var,,}
变量拓展
扩展以所有prefix开头的变量
${!prefix*}
${!prefix@}
[root@centos8 data]#wz1=1;wz2=2;wz3=3
[root@centos8 data]#echo ${!wz*}
wz1 wz2 wz3
高级变量赋值
如下:var 和 str 为变量,针对 str 是否有设定来决定 var 的值。
- [str:]代表 str 没有设定或为空的字符串
- [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 |
array:数组
介绍
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,相当于多个变量集合
数组名和索引
- 索引的编号从0开始,属于数值索引
- 索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash4.0版本后支持
- bash的数组支持索引不连续
声明数组
普通数组可不事先声明,直接使用
declare -a array_name
关联数组必须事先声明,再使用
declare -A array_name
两者不可相互转换
赋值
- 一次只赋值一个元素
array_name[index]=value
week[1]="one"
week[2]="two"
- 一次赋值全部元素
array_name=("var1" "var2" ...)
name=("zhangsan" "lisi" "wangwu")
serial=({1..10})
alpha=({a..z})
file=(*.sh)
- 只赋值特定元素
array_name=([0]="var1" [3]="var2" ...)
title=([0]="a" [3]="b" [9]="c")
引用
- 显示所有数组
delcare -a
- 引用特定数组元素
${array_name[index]} 如果省略[index]下标将引用下标为0的元素
[root@centos8 data]#declare -a title=([0]="a" [3]="b" [4]="c")
[root@centos8 data]#echo ${title[3]}
b[root@centos8 data]#echo ${title}
a
- 引用数组所有元素
${array_name[*]} 将所有数组元素视为一个整体
${array_name[@]} 将每个数组元素视为单独的个体
[root@centos8 data]#declare -a title=([0]="a" [3]="b" [4]="c")
[root@centos8 data]#echo ${title[*]}
a b c
[root@centos8 data]#echo ${title[@]}
a b c
- 数组长度或数组中元素个数
${#array_name[*]}
${#array_name[@]}
[root@centos8 data]#declare -a title=([0]="a" [3]="b" [4]="c")
[root@centos8 data]#echo ${#title[*]}
3
[root@centos8 data]#echo ${#title[@]}
3
- 数组的所有下标
${!array_name[*]}
${!array_name[@]}
[root@centos8 data]#declare -a title=([0]="a" [3]="b" [4]="c")
[root@centos8 data]#echo ${!title[@]}
0 3 4
[root@centos8 data]#echo ${!title[*]}
0 3 4
删除
- 删除数组中某个元素会使索引不连续
unset array_name[index]
[root@centos8 data]#declare -a title=([0]="a" [3]="b" [4]="c")
[root@centos8 data]#unset title[3]
[root@centos8 data]#echo ${title[@]}
a c
- 删除整个数组
unset array_name
[root@centos8 data]#unset title
数组数据处理
${array_name[@]:offset:number}
${array_name[*]:offset:number}
- offset指要跳过的元素个数
- number指取出的元素个数
取出指定偏移量后(跳过几个)的所有元素
${array_name[@]:offset}
${array_name[*]:offset}
[root@centos8 data]#num=({1..10})
[root@centos8 data]#echo ${num[*]}
1 2 3 4 5 6 7 8 9 10[root@centos8 data]#echo ${num[*]:2:4}
3 4 5 6[root@centos8 data]#echo ${num[*]:3}
4 5 6 7 8 9 10
向数组中追加元素
array[${#array[*]}]=value
array[${#array[@]}]=value
[root@centos8 data]#num=({1..10})
[root@centos8 data]#num[${#num[@]}]=11
[root@centos8 data]#echo ${num[*]}
1 2 3 4 5 6 7 8 9 10 11
常用通配符
通配符常用于命令行或脚本等bash环境
* 匹配0个或无穷个任意字符
[root@wzy data]#touch abc.txt ab.txt a.txt
[root@wzy data]#ls a*.txt
abc.txt ab.txt a.txt
[root@wzy data]#ls a*
abc.txt ab.txt a.txt
? 匹配一个任意字符
[root@wzy data]#touch a.txt ab.txt abc.txt adc.txt
[root@wzy data]#ls a?c.txt
abc.txt adc.txt
[root@wzy data]#ls a?.txt
ab.txt
[xxx] 匹配中括号内的任意一个字符;[0-9] 代表0到9之间所有数字
[root@wzy data]#touch a.txt ab.txt abc.txt abcd.txt abce.txt
[root@wzy data]#ls a[bcd].txt
ab.txt
[root@wzy data]#ls abc[de].txt
abcd.txt abce.txt
[-] 中括号内有减号,代表在编码顺序内的所有字符;[0-9] 代表0到9之间所有数字
[root@wzy data]#touch a{0..9}.txt;ls
a0.txt a1.txt a2.txt a3.txt a4.txt a5.txt a6.txt a7.txt a8.txt a9.txt
[root@wzy data]#ls a[1-3].txt
a1.txt a2.txt a3.txt
[^] 中括号内有指数符号,代表反向;[^abc] 代表有一个非a或b或c的字符
[root@wzy data]#ls a[^7-9].txt
a0.txt a1.txt a2.txt a3.txt a4.txt a5.txt a6.txt
常用特殊符号
通配符 | 说明 |
; | 连续命令的分隔符 |
# | 注释符号,其后面的数据均不执行 |
\ | 跳脱符号、转义符,将特殊符号或通配符转换为一般文本字符 |
~ | 用户的家目录 |
- | 上次的工作目录 |
. | 当前工作目录 |
.. | 上级目录 |
$ | 使用变量前需要加的符号 |
& | 工作控制,将指令变成背景下工作 |
/ | 目录符号,路径分割符 |
! | 逻辑运算中的“非” |
() | 小括号,在中间为子shell的起始与结束 |
{} | 花括号,在中间为命令区块的组合 |
"":双引号,中间内容特殊符号、通配符或变量保持原有特性
[root@wzy data]#name=zhangsan
[root@wzy data]#echo "$name"
zhangsan
'':单引号,中间内容转变为纯文本
[root@wzy data]#echo '$name'
$name
``:反引号,中间内容优先执行
[root@wzy data]#echo date
date
[root@wzy data]#echo `date`
Sat Apr 15 11:02:11 CST 2023
标准输入、标准输出、标准错误输出
标准输入stdin :代码0,使用 < 或 <<;< 将原本由键盘输入的内容由文件内容取代 ,<< 结束标志的输入字符
[root@wzy data]#vim name
zhangsan
lisi[root@wzy data]#cat > newfile < name
[root@wzy data]#ll
total 8
-rw-r--r-- 1 root root 14 Apr 15 10:30 name
-rw-r--r-- 1 root root 14 Apr 15 10:31 newfile
[root@wzy data]#cat newfile
zhangsan
lisi
标准输出stdout :代码1,使用 > 或 >>;> 代表覆盖,>> 代表追加
标准错误输出stderr:代码2,使用 2> 或 2>>
无论正确错误都指向一个位置:&>
#使用一般身份账号wenzi搜寻 /home 目录下是否有名为 .bashrc 的文件存在
[wenzi@wzy ~]$find /home -name .bashrc
/home/roo/.bashrc 此行正常输出
/home/wenzi/.bashrc 此行正常输出
find: ‘/home/wenzi/encrypt’: Permission denied 此行是错误输出#将上述stdout和stderr分别存储到不同的文件中
[wenzi@wzy ~]$find /home -name .bashrc > stdout.txt 2> stderr.txt
[wenzi@wzy ~]$cat stdout.txt
/home/roo/.bashrc
/home/wenzi/.bashrc
[wenzi@wzy ~]$cat stderr.txt
find: ‘/home/wenzi/encrypt’: Permission denied#将错误的数据丢弃,屏幕只显示正确的数据
[wenzi@wzy ~]$find /home -name .bashrc 2>/dev/null
/home/roo/.bashrc
/home/wenzi/.bashrc
#将指令的数据全部写入名为list.txt的文件中[wenzi@wzy ~]$find /home -name .bashrc &>list.txt
[wenzi@wzy ~]$cat list.txt
/home/roo/.bashrc
/home/wenzi/.bashrc
find: ‘/home/wenzi/encrypt’: Permission denied
高级用法
命令 <<< "字符串"
[root@centos8 ~]# seq -s + 10
1+2+3+4+5+6+7+8+9+10
[root@centos8 ~]# seq -s + 10 > rs.txt;bc < rs.txt
55
等同于
[root@centos8 ~]# bc <<< `seq -s + 10`
55
指令回传值$? 与&& 或||
若前一个命令执行结果为正确,在linux下会回传一个 $? = 0 的值,错误为1
&& 代表 and ,并且;
|| 代表 or,或者;
通常情况下判断式为三个,通常写作如此 command1 && command2 || command2
#测试当前目录下ceshi目录是否存在,若存在创建/ceshi/aaa文件
[root@wzy data]#ls ./ceshi && touch ./ceshi/aaa
ls: cannot access './ceshi': No such file or directory
[root@wzy data]#mkdir ceshi
[root@wzy data]#ls ./ceshi && touch ./ceshi/aaa
[root@wzy data]#ls ./ceshi
aaa#测试当前目录下tmp/abc目录是否存在,若不存在则创建tmp/abc,若存在则无操作
root@wzy data]#ls tmp/abc || mkdir -p tmp/abc
[root@wzy data]#ls
tmp
[root@wzy data]#ls tmp/
abc#使用三联判断式
[root@wzy data]#ls tmp/abc || mkdir -p tmp/abc && touch tmp/abc/one
ls: cannot access 'tmp/abc': No such file or directory
[root@wzy data]#ls tmp/abc/one
tmp/abc/one
管道命令 |
管道命令仅能处理由前一个指令传来的正确信息,即standard output的信息,对于standard errror没有直接处理能力,会予以忽略
选取命令
cut:取出一行信息中目标部分
cut -d ’分割字符’ -f 第几段 用于有特定分割字符
-d:后面接分割字符,与-f一起使用
-f:依据-d的分割字符将一段信息分为数段,用-f取出第几段
cut -c 字符区间 用于排列整齐信息
-c:以字符的单位取出固定字符区间
#取出PATH变量中以:分割后的第五段字符
[root@wzy ~]#echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@wzy ~]#echo ${PATH} | cut -d ':' -f 5
/root/bin#取出PATH变量中以:分割后的第三段和第五段字符
[root@wzy ~]#echo ${PATH} | cut -d ':' -f 3,5
/usr/sbin:/root/bin#将export输出的前五行信息,取出第12字符以后的所有字符串
[root@wzy ~]#export | head -5
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
declare -x DISPLAY="localhost:10.0"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
[root@wzy ~]#export | head -5 | cut -c 12-
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/0/bus"
DISPLAY="localhost:10.0"
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/root"#将last命令显示的前五行登录者信息中仅留下用户大名
[root@wzy ~]#last | head -5
root pts/0 192.168.29.1 Sat Apr 15 10:19 still logged in
wenzi pts/0 192.168.29.1 Sat Apr 15 10:09 - 10:19 (00:09)
root pts/0 192.168.29.1 Sat Apr 15 10:01 - 10:09 (00:07)
wenzi pts/0 192.168.29.1 Sat Apr 15 10:00 - 10:01 (00:00)
root pts/0 192.168.29.1 Sat Apr 15 09:03 - 09:59 (00:56)
[root@wzy ~]#last | head -5 | cut -d ' ' -f 1
root
wenzi
root
wenzi
root
grep:分析一行信息,若该行有目标信息则取出该行
grep [-acinv] [--color=auto] '搜寻字符串' 文件名
-a:将binary文件以text文件的方式搜寻数据
-c:计算找到“搜寻字符串”的次数
-i:忽略大小写差异
-n:输出行号
-v:反向选择,即没有“搜寻字符串”的行
--color=auto:可以将找到的关键字部分加上颜色高亮显示
[root@wzy ~]#last | head -5
root pts/0 192.168.29.1 Sat Apr 15 10:19 still logged in
wenzi pts/0 192.168.29.1 Sat Apr 15 10:09 - 10:19 (00:09)
root pts/0 192.168.29.1 Sat Apr 15 10:01 - 10:09 (00:07)
wenzi pts/0 192.168.29.1 Sat Apr 15 10:00 - 10:01 (00:00)
root pts/0 192.168.29.1 Sat Apr 15 09:03 - 09:59 (00:56)#过滤出含有root用户行
[root@wzy ~]#last | head -5 | grep 'root'
root pts/0 192.168.29.1 Sat Apr 15 10:19 still logged in
root pts/0 192.168.29.1 Sat Apr 15 10:01 - 10:09 (00:07)
root pts/0 192.168.29.1 Sat Apr 15 09:03 - 09:59 (00:56)#过滤出不含有root用户行
[root@wzy ~]#last | head -5 | grep -v 'root'
wenzi pts/0 192.168.29.1 Sat Apr 15 10:09 - 10:19 (00:09)
wenzi pts/0 192.168.29.1 Sat Apr 15 10:00 - 10:01 (00:00)
排序命令
sort
sort [-fbMnrtuk] [ file or stdin ]
-f:忽略大小写,例如A和a视为编码相同
-b:忽略最前面的空格符部分
-M:以月份名字排序,例如JAN,DEC等排序方法
-n:以纯数字进行排序,默认以文字形态排序
-r:反向排序
-u:即uniq去除重复,相同的数据仅显示一行
-t:分隔符,默认以tab键分割
-k:以某个区间排序
#默认以文字形态排序;sort预设以第一个数据排序,如adm和avahi账号顺序
[root@wzy ~]#cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:993:988::/var/lib/chrony:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin#/etc/passwd默认以:分隔,使以第三栏排序
[root@wzy ~]#cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
wenzi:x:1000:1001:wenzi:/home/wenzi:/bin/bash
qemu:x:107:107:qemu user:/:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
#并使用数字排序[root@wzy ~]#cat /etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin#利用last,将输出的数据仅取账号,并加以排序.。(第一行空格是last默认字符,可忽略)
[root@wzy ~]#last | cut -d ' ' -f 1 | sort
reboot
reboot
root统计日志访问量
[root@centos8 data]#cut -d" " -f1 /var/log/nginx/access_log | sort -u | wc -l
uniq
uniq [选项] [文件]
-i:忽略大小写
-c:计数,显示某行连续重复出现的次数,所以是先 sort 再 uniq -c
-d:仅显示重复过的行
-u:仅显示不曾重复的行
常和sort命令一起使用:sort userlist.txt | uniq -c
#使用last仅将账号列出,进行排序后去重,并显示每个人的登录次数。
[root@wzy ~]#last | cut -d ' ' -f 1 | sort | uniq -c
1
15 reboot
1 roo
32 root
1 wenzi
1 wtmp
wc
wc [-lwm]
-l:多少行
-w:多少字数
-m:多少字符数,空格、回车也算一个字符
-c:多少字节数
-L:显示一个文件中最长行的长度
[root@wzy ~]#cat test.txt
aab c
dd
[root@wzy ~]#wc -c test.txt
10 test.txt
[root@wzy ~]#wc -m test.txt
10 test.txt
[root@wzy ~]#wc -L test.txt
6 test.txt
[root@wzy ~]#wc -l test.txt
2 test.txt
[root@wzy ~]#wc -w test.txt
3 test.txt
[root@wzy ~]#cat -A test.txt
aab c$
dd$[root@centos8 data]#cat cs.txt
1 zs # 1是1个字节、空格是1个字节、z是一个字节、s是一个字节、换行符是一个字节,此
2 ls 行共5个字节
3 w
[root@centos8 data]#cat ab.txt
1 zs
2 ls
3 王 #汉字是3个字节,此行共6个字节
[root@centos8 data]#wc cs.txt
3 6 14 cs.txt
[root@centos8 data]#wc ab.txt
3 6 16 ab.txt
双重重定向
tee:同时将数据流分送到文件和屏幕
tee [-a] file
-a:以追加的方式将数据加入file中。默认是覆盖
#取last前五行存到last.txt文件并在屏幕上仅显示前五行的账号
[root@wzy ~]#last | head -5 | tee last.txt | cut -d ' ' -f 1
root
root
root
root
root
[root@wzy ~]#cat last.txt
root pts/0 192.168.29.1 Sun Apr 23 01:42 still logged in
root pts/2 192.168.29.1 Sat Apr 22 16:16 - 01:14 (08:57)
root pts/1 192.168.29.1 Sat Apr 22 16:16 - 16:16 (00:00)
root pts/0 192.168.29.1 Sat Apr 22 16:15 - 16:16 (00:00)
root pts/0 192.168.29.1 Thu Apr 20 07:00 - 07:01 (00:00)
字符转换命令
tr
tr [-ds] '字符串'
-d:删除讯息中的字符串
-s:把连续重复的字符以单独一个字符表示
#将所有小写变为大写
[root@wzy ~]#last | head -5 | tr '[a-z]' '[A-Z]'
ROOT PTS/0 192.168.29.1 SUN APR 23 01:42 STILL LOGGED IN
ROOT PTS/2 192.168.29.1 SAT APR 22 16:16 - 01:14 (08:57)
ROOT PTS/1 192.168.29.1 SAT APR 22 16:16 - 16:16 (00:00)
ROOT PTS/0 192.168.29.1 SAT APR 22 16:15 - 16:16 (00:00)
ROOT PTS/0 192.168.29.1 THU APR 20 07:00 - 07:01 (00:00)#将分割符:删除
[root@wzy ~]#cat /etc/passwd | head -5 | tr -d ':'
rootx00root/root/bin/bash
binx11bin/bin/sbin/nologin
daemonx22daemon/sbin/sbin/nologin
admx34adm/var/adm/sbin/nologin
lpx47lp/var/spool/lpd/sbin/nologin
col
col [-xb]
-x:将tab键转换成对等的空格键。Tab以^I表示
root@wzy ~]#cat -A abcd
abc d^Ie$
[root@wzy ~]#cat abcd | col -x | cat -A | more
abc d e$
join:两个文件中有相同数据的行,才将它加在一起
join [-til2] file1 file2
-t:join默认以空格符分隔数据,并且对比第一个字段的数据,如果两个文件相同,则将两笔数据联成一行,且第一个字段放在第一个。
-i:忽略大小写
-1:数字1,表示第一个文件用某个字段分析
-2:数字2,表示第二个文件用某个字段分析
使用join前需要事先进行排序
#用root的身份,将/etc/passwd与/etc/shadow相关数据整合为一行
[root@wzy ~]#head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin==> /etc/shadow <==
root:$6$pZLLx.uz1Qxz9yqu$MqVJwUTPCW6rM7TRo/O8H8ZXzIyEZw1biH/dORoXigqglsmIsS6xBFqCNVx/2rFqAnuKSqF9LpfIq7jOE9498.::0:99999:7:::
bin:*:18358:0:99999:7:::
daemon:*:18358:0:99999:7:::
[root@wzy ~]#join -t ':' /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash:$6$pZLLx.uz1Qxz9yqu$MqVJwUTPCW6rM7TRo/O8H8ZXzIyEZw1biH/dORoXigqglsmIsS6xBFqCNVx/2rFqAnuKSqF9LpfIq7jOE9498.::0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:18358:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18358:0:99999:7:::
#/etc/passwd第四个字段是GID,/etc/group第三个字段是GID,如何整合两个文件[root@wzy ~]#head -n 3 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin==> /etc/group <==
root:x:0:
bin:x:1:
daemon:x:2:
[root@wzy ~]#join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
join: /etc/passwd:6: is not sorted: sync:x:5:0:sync:/sbin:/bin/sync
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:
join: /etc/group:11: is not sorted: wheel:x:10:roo,wenzi
paste:将两行贴在一起,且中间以tab键隔开,无需对比相关性
paste [-d] file1 file2
-d:后可接分隔字符,默认以tab键隔开
-:如果file部分写成-,表示来自标准输入
#将/etc/passwd与/etc/shadow同一行贴在一起且取前3行
[root@wzy ~]#paste /etc/passwd /etc/shadow | head -3
root:x:0:0:root:/root:/bin/bash root:$6$pZLLx.uz1Qxz9yqu$MqVJwUTPCW6rM7TRo/O8H8ZXzIyEZw1biH/dORoXigqglsmIsS6xBFqCNVx/2rFqAnuKSqF9LpfIq7jOE9498.::0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:18358:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:18358:0:99999:7:::#将/etc/group读出,然后与上述贴在一起且取前三行。注意-符号
[root@wzy ~]#cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
root:x:0:0:root:/root:/bin/bash root:$6$pZLLx.uz1Qxz9yqu$MqVJwUTPCW6rM7TRo/O8H8ZXzIyEZw1biH/dORoXigqglsmIsS6xBFqCNVx/2rFqAnuKSqF9LpfIq7jOE9498.::0:99999:7::: root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:18358:0:99999:7::: bin:x:1:
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:18358:0:99999:7::: daemon:x:2:[root@centos8 data]#seq 5 > a.txt
[root@centos8 data]#cat a.txt
1
2
3
4
5
[root@centos8 data]#echo -e "a\nb\nc\nd\ne" > b.txt
[root@centos8 data]#cat b.txt
a
b
c
d
e
[root@centos8 data]#paste a.txt b.txt
1 a
2 b
3 c
4 d
5 e
[root@centos8 data]#paste -d":" a.txt b.txt
1:a
2:b
3:c
4:d
5:e
[root@centos8 data]#paste -s a.txt
1 2 3 4 5
[root@centos8 data]#paste -s a.txt b.txt
1 2 3 4 5
a b c d e
[root@centos8 data]#paste -s -d":" a.txt b.txt
1:2:3:4:5
a:b:c:d:e批量更改用户密码
[root@centos8 data]#cat name.txt
zhangsan
lisi
[root@centos8 data]#cat pwd.txt
zs
ls
[root@centos8 data]#paste -d ":" name.txt pwd.txt
zhangsan:zs
lisi:ls
[root@centos8 data]#paste -d ":" name.txt pwd.txt | chpasswd
expand
expand [-t] file
-t:后面可接数字自定义一个tab键代表多少空格键。通常一个tab键用8个空格键取代,
# ^I表示tab键 ¥表示回车
[root@wzy ~]#grep "^MANPATH" /etc/man_db.conf | head -3
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /sbin /usr/share/man
[root@wzy ~]#grep "^MANPATH" /etc/man_db.conf | head -3 | cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$
分割文件
split:依据文件大小分割文件
split [-bl] file PREFIX
-b:后面可接欲分割成的文件大小 ,默认-b表示以b字节为单位。可加单位,如k、m等
-l:以行数分割
PREFIX:代表前导符,可作为分割文件的前导文字
#以文件大小分割
[root@wzy ~]#ll -h
-rwxr-xr-x 1 root root 1.2K Mar 29 22:06 initenv.sh[root@wzy ~]#split -b 1k initenv.sh initenv
[root@wzy ~]#ll -h
-rw-r--r-- 1 root root 1.0K Apr 23 04:06 initenvaa
-rw-r--r-- 1 root root 196 Apr 23 04:06 initenvab
-rwxr-xr-x 1 root root 1.2K Mar 29 22:06 initenv.sh#合并
[root@wzy ~]#cat initenva* >> initenv.txt
#以行数分割
[root@wzy ~]#cat abc
aa
bb
cc
dd
[root@wzy ~]#split -l 2 abc abc
[root@wzy ~]#ll
total 40
-rw-r--r-- 1 root root 12 Apr 23 04:15 abc
-rw-r--r-- 1 root root 6 Apr 23 04:16 abcaa
-rw-r--r-- 1 root root 6 Apr 23 04:16 abcab
比较文件
diff
默认情况下,diff
命令输出的结果使用一种简单的、基于行的差异报告格式。它会指出哪些行需要删除(用 d
表示)、添加(用 a
表示)或更改(用 c
表示)以使两个文件相匹配。
2c2
< 12
---
> 12a
4d3
< 1234
5a5
> b
-
d
:Delete(删除)。这表示在第一个文件中的某些行在第二个文件中不存在。比如10,12d9
表示第一个文件的第10到12行需要被删除以匹配第二个文件的第9行之前的状态。 -
a
:Add(添加)。这意味着某些行在第一个文件中不存在,但在第二个文件中存在。例如9a11,13
表示为了使第一个文件与第二个文件相匹配,在第一个文件的第9行之后需要添加第11至13行的内容。 -
c
:Change(更改)。表示两个文件之间某部分的内容不同。例如12,13c12,13
指出第一个文件的第12到13行与第二个文件的第12到13行内容不相同,需要替换。
- 第二行发生了改变(
2c2
),a.txt
中的 "12" 被替换为b.txt
中的 "12a"。 - 第四行被从
a.txt
中删除了(4d3
),即 "1234" 不在b.txt
中。 - 在
a.txt
的第五行之后,b.txt
添加了一行 "b"(5a5
)。
diff -u
使用统一上下文模式生成更易读的差异报告。它显示每个文件中的变化,并通过几行上下文来帮助理解变更的位置。它使用 -
来表示第一个文件中被移除的行,使用 +
来表示第二个文件中新增加的行。
@@ -1,5 +1,6 @@
1
-12
+12a
+123
123
-1234
12345
+b
@@ -1,5 +1,6 @@
指出接下来的块是关于a.txt
的第1到第5行以及b.txt
的第1到第6行的变化。-12
表示a.txt
中的 "12" 被移除了。+12a
和+123
表明在b.txt
相应位置增加了这两行。-1234
指出a.txt
中的 "1234" 被移除了。- 最后的
+b
显示b.txt
在末尾增加了一个额外的 "b" 字符。
格式化打印
printf
printf '打印格式' 实际内容
\n:换行符,输出新的一行
\r:回车符,enter键
\t:水平制表符,tab键
\v:垂直制表符
\b:退后一格
%s:表示任意长度的字符串
%ns:n是数字,s是字符串,即多少个字符
%ni:n是数字,i是数字,即多少整数字数
%N.nf:n、N都是数字,f是浮点数。假设共要十个位数,小数点有两位,即%10,2f
[root@centos8 data]#printf "%s \t %s \t %s \t %s\n" "姓名" "性别" "年龄" "分数" "小明" "男" "18" "60" "小红" "女" "19" "82.5" "小蓝" "男" "18" "98.75" > list.txt
[root@centos8 data]#cat list.txt
姓名 性别 年龄 分数
小明 男 18 60
小红 女 19 82.5
小蓝 男 18 98.75
[root@centos8 data]#printf '%5s %5s %5i \t %4.2f \n' `cat list.txt | awk 'NR>1 {print $0}'`
小明 男 18 60.00 将小数点后的两位也显示出来
小红 女 19 82.50
小蓝 男 18 98.75
[root@centos8 data]#printf '%5s %5s %5i \t %4.1f \n' `cat list.txt | awk 'NR>1 {print $0}'`
小明 男 18 60.0
小红 女 19 82.5
小蓝 男 18 98.8 四舍五入了
参数代换
xargs
xargs [-Oepn] command
-O:如果输入的有特殊字符,此参数可将其视为普通文本
-e:及EOF(end of file),后可接一个字符串,当xargs分析到此字符串时就会停止工作。-e和字符串之间没有空格。
-p:执行每个指令的参数时都会询问
-n:后接次数,每次command执行时要使用几个参数
当xargs后没有接任何指令时,默认以echo输出
#错误示范。虽然$()可预先取得参数,但是id命令仅能接收一个参数
[root@wzy ~]#id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
#错误示范。id不是管线命令,显示结果不是想要的
[root@wzy ~]#cut -d ':' -f 1 /etc/passwd | head -3 | id
uid=0(root) gid=0(root) groups=0(root)
#正确写法。-n指定每次传递一个参数[root@wzy ~]#cut -d ':' -f 1 /etc/passwd | head -3 | xargs -p -n 1 id
id root ?...y
uid=0(root) gid=0(root) groups=0(root)
id bin ?...y
uid=1(bin) gid=1(bin) groups=1(bin)
id daemon ?...y
uid=2(daemon) gid=2(daemon) groups=2(daemon)
安装复制文件
install
install功能相当于cp、chmod、chown、chgrp、mkdir等相关工具集合
install [OPTION]... [-T] SOURCE DEST
install [OPTION]... SOURCE... DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE...
install [OPTION]... -d DIRECTORY...
Option:
-m 权限,默认755
-o 所属主
-g 所属组
-d 目录
复制/etc/passwd 文件到 /data 目录下,并将passwd文件权限设置为666,属主为wang,属组root
[root@centos8 data]# install -m 666 -o wang -g root /etc/passwd /data/
[root@centos8 data]# ll
total 4
-rw-rw-rw- 1 wang root 2658 Nov 22 22:46 passwd
[root@centos8 data]# ll /etc/passwd
-rw-r--r--. 1 root root 2658 Nov 14 01:17 /etc/passwd
关于减号-的用途
在管道命令中,常会使用到前一个指令的stdout作为本次的stdin,某些命令需要文件名来处理时可用减号 – 来替代stdout或stdin
mkdir /tmp/homeback
tar -cv -f /home | tar -xv -f - -C /tmp/homeback
我将/home中数据打包,但打包后数据不是记录到文件,而是传递到stdout;经过管道命令将 tar -cv -f /home 结果传递给 tar -xv -f –