当前位置: 首页 > 工具软件 > bash2mp4 > 使用案例 >

Linux bash基础知识

羊舌青青
2023-12-01

10.1 认识BASH这个shell

10.1.1 硬件、内核与shell

操作系统一组控制整个硬件与检测管理系统活动的软件
shell广义而言是指能够操作应用程序的软件,狭义的shell指的是命令行方面的软件

10.1.2 为何要学习命令模式的shell

1、屏蔽操作系统差异,几乎各家的Linux发行版bash都是一样的。

2、远程管理时命令行模式比较快。

3、是学习Linux的任督二脉

10.1.3 系统的合法shell与 /etc/shells功能

[root@localhost ~]# cat /etc/shells 
/bin/sh (已经被bin/bash 替代)
/bin/bash (是Linux默认的shell)
/usr/bin/sh
/usr/bin/bash

Q:用户什么时候取得shell来工作?

A:当用户登陆系统后

[root@localhost ~]# cat /etc/passwd
passwd   passwd-  
[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
zyg:x:1000:1000:zyg:/home/zyg:/bin/bash
nginx:x:997:994:nginx user:/var/cache/nginx:/sbin/nologin
mysql:x:996:993:MySQL server:/var/lib/mysql:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

10.1.4 Bash shell的功能

历史命令【history】。在命令行模式通过【上下键】可以找到前后一个输入的命令,默认记录1000个
命令与文件补全【tab】。它可以少打很多字以及确认命令是正确的,如果安装了bash-completion,还可以选项补全
命令别名设置功能【alias】,通过将常用命令组合设置别名可提高效率等,如ls -l设置别名ll
任务管理、前台、后台控制使用前后台控制可以让任务进行的更为顺利,而任务管理可以随时将任务丢到后台运行而不怕不小心被【ctrl + c】中断
程序化脚本通过sshell脚本实现命令的批量处理。
通配符查询bash支持许多通配符来帮助用户查询和命令执行

10.1.5 查询命令是否为Bash shell内置命令:【type】

-t以下字符表示命令的类型

①file: 外部命令

②alias:该命令为命令别名设置的名称

③builtin:该命令为bash内置的命令功能
-p显示完整的文件名
-a将所有含name的命令都列出来,包含alias
[root@localhost ~]# type ls
ls 是 `ls --color=auto' 的别名
[root@localhost ~]# type -t ls
alias
[root@localhost ~]# type -a ls
ls 是 `ls --color=auto' 的别名
ls 是 /usr/bin/ls

10.1.6 命令的执行与快速编辑按钮

Q:命令如何换行执行?

A:通过【\[Enter]】转接,其中’\'与Enter之间没有任何符号,若第二行出现">"字符则说明创建成功。

[root@localhost linux]# mkdir \
> test1
[root@localhost linux]# ls
test  test1

shell快速编辑按钮

【ctrl】 + u从光标处向前删除命令串
【ctrl】+ k从光标处向后删除命令串
【ctrl】+ a让光标移动到整个命令串的最前面
【ctrl】+ e让光标移动到整个命令串的最后面

10.2 Shell的变量功能

10.2.1 什么是变量?

定义:让某一个特定字符串代表不固定的内容,简单地说【y = ax+b】等号左边的就是变量。

10.2.2 变量的使用与设置【echo】、【unset】

变量的使用【echo】

[root@localhost linux]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost linux]# echo $HOME
/root
[root@localhost linux]# echo $variable #当一个变量未被设置时,结果为空

变量的设置规则

①变量与变量内容以一个等号【=】连接: name=VBird

②等号两边不能直接连接空格:name = VBird(x)

[root@localhost linux]# name = VBird
-bash: name: 未找到命令

③变量内容若有空格可使用双引号【“】或单引号【'】将变量内容结合起来。但双引号可保留原有的特性,单引号仅为一般字符。

[root@localhost linux]# echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost linux]# echo '$PATH'
$PATH

④可用转义字符【\】将特殊字符转化为一般字符

[root@localhost linux]# myname=VBird\ Tsai
[root@localhost linux]# echo $myname
VBird Tsai

⑤在命令执行时需要引用其他命令时可以使用反引号”`“或使用$(command)

[root@localhost linux]# version=`uname -r`
[root@localhost linux]# echo $version
3.10.0-1160.83.1.el7.x86_64
[root@localhost linux]# echo $(ls)
test test1

⑥若该变量为扩增变量内容时,则可用” 变量名称“或 变量名称“或 变量名称{变量名称}

[root@localhost linux]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost linux]# PATH="$PATH":/home/bin
[root@localhost linux]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin

⑦若该变量需要在其他子程序执行时,则需要以export来使用变量变成环境变量(注:可通过export -n PATH取消扩展c’c’x)

[root@localhost linux]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin
[root@localhost linux]# sh
sh-4.2# echo $PATH
/usr/local/bin:/usr/bin
sh-4.2# exit
exit
[root@localhost linux]# export PATH
[root@localhost linux]# sh
sh-4.2# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin

⑧通常大写字符为系统默认字符,自行设置变量可以使用小写字符,方便判断

⑨取消变量的方法为【unset 变量名称】

[root@localhost linux]# echo $myname
VBird Tsai
[root@localhost linux]# unset myname
[root@localhost linux]# echo $myname


10.2.3 环境变量的功能【set】

[root@localhost linux]# env
XDG_SESSION_ID=1  #Xorg的配置信息
HOSTNAME=localhost.localdomain  #主机名
SELINUX_ROLE_REQUESTED=  
TERM=xterm    #这个终端使用的环境类型是什么
SHELL=/bin/bash   #目前该环境下使用的shell程序是什么
HISTSIZE=1000     #history 默认记录1000条数据
SSH_CLIENT=192.168.10.10 51518 22  #SSH远程连接的客户端IP信息
SELINUX_USE_CURRENT_RANGE=
OLDPWD=/root  #上一个工作目录所在
SSH_TTY=/dev/pts/0
USER=root
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:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=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:*.jpg=01;35:*.jpeg=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:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=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:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:  #ls命令的颜色设置
MAIL=/var/spool/mail/root  #使用者所使用的mailbox位置
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/bin
PWD=/root/linux  #当前的工作目录
LANG=zh_CN.UTF-8  #当前工作的语言
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups  
SHLVL=1
HOME=/root   #使用者的家目录
LOGNAME=root
SSH_CONNECTION=192.168.10.10 51518 192.168.10.247 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

观察所有变量【set】

set可显示包括环境变量以及个人变量在内的所有变量信息

[root@localhost linux]# set | more
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_REMATCH=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=168
COMP_WORDBREAKS=$' \t\n"\'><=;|&(:'
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/root
PS1='[\u@\h \W]\$ '

令:在man手册中关于PS1的说明

       When executing interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input
       to  complete a command.  Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as
       follows:
              \a     an ASCII bell character (07)
              \d     the date in "Weekday Month Date" format (e.g., "Tue May 26")
              \D{format}
                     the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time  rep?
                     resentation.  The braces are required
              \e     an ASCII escape character (033)
              \h     the hostname up to the first `.'
              \H     the hostname
              \j     the number of jobs currently managed by the shell
              \l     the basename of the shell's terminal device name
              \n     newline
              \r     carriage return
              \s     the name of the shell, the basename of $0 (the portion following the final slash)
              \t     the current time in 24-hour HH:MM:SS format
              \T     the current time in 12-hour HH:MM:SS format
              \@     the current time in 12-hour am/pm format
              \A     the current time in 24-hour HH:MM format
              \u     the username of the current user
              \v     the version of bash (e.g., 2.00)
              \V     the release of bash, version + patch level (e.g., 2.00.0)
              \w     the current working directory, with $HOME abbreviated with a tilde (uses the value of the PROMPT_DIRTRIM variable)
              \W     the basename of the current working directory, with $HOME abbreviated with a tilde
              \!     the history number of this command
              \#     the command number of this command
              \$     if the effective UID is 0, a #, otherwise a $
              \nnn   the character corresponding to the octal number nnn
              \\     a backslash
              \[     begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
              \]     end a sequence of non-printing characters

10.2.4 影响显示结果的语系变量【locale】

[root@localhost linux]# locale 
LANG=zh_CN.UTF-8  #主语言环境
LC_CTYPE="zh_CN.UTF-8"  #字符(文字)辨识的编码
LC_NUMERIC="zh_CN.UTF-8"  #数字系统的显示信息
LC_TIME="zh_CN.UTF-8"  #时间系统的显示数据
LC_COLLATE="zh_CN.UTF-8"  #字符的比较与排序等
LC_MONETARY="zh_CN.UTF-8"  #币值格式的显示
LC_MESSAGES="zh_CN.UTF-8"  #信息显示的内容,如功能表、错误信息等
LC_PAPER="zh_CN.UTF-8"  
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=  #整体语言环境

#通常只需要设置LANG以及LC_ALL即可

10.2.5 变量的有效范围

①当启动一个shell,操作系统会分配一内存区域给shell使用,此内存中的变量可以让子进程使用。

②在父进程利用export功能,可以让自定义变量的内容写到上述的内存区域中(环境变量)。

③当加载另一个shell时,子shell可以将父shell的环境变量所在的内存区域导入自己的环境变量区块中。

10.2.6 变量键盘读取、数组与声明【read】、【declare】

【read】读取来自键盘输入的变量

-p后面可以接提示字符
-t后面可以接受等待的秒数,不会一直等待使用者
[root@localhost linux]# read atest
This is a test
[root@localhost linux]# echo $atest
This is a test

[root@localhost linux]# read -t 3 atest
this is a [root@localhost linux]# this is a test
-bash: this: 未找到命令

【declare】声明变量类型

-a将变量定义为数组类型(array)
-i将变量定义为整数类型(integer)
-x将后面的变量定义为环境变量,用法与export一样
-r将变量设置为readonly类型,该变量不能被更改内容,也不能被unset,需要注销登录才能恢复。
[root@localhost linux]# sum=100+30+50
[root@localhost linux]# echo $sum
100+30+50
[root@localhost linux]# declare -i sum=100+30+50
[root@localhost linux]# echo $sum
180
[root@localhost linux]# var[1]="small ming"
[root@localhost linux]# echo "${var[1]}"
small ming
[root@localhost linux]# echo "${var[2]}"

[root@localhost linux]# var[2]="big ming"
[root@localhost linux]# var[3]="nice ming"
[root@localhost linux]# echo "${var[1]},${var[2]},${var[3]}"
small ming,big ming,nice ming

10.2.7 与文件系统及程序的限制关系:【ulimit】

-Hhard limit,严格的限制,必定不能超过这个限制
-Ssoft limit,警告的限制,可以超过,但是超过会有告警信息
-a列出所有限制额度
-c限制每个内核文件的最大容量
-f此shell可以建立的最大容量,单位为Kbytes
-d程序可使用的最大段内存容量
-l可用于锁定的内存量
-t可使用的最大CPU时间
-u单一使用者可以使用的最大进程数量
[root@localhost linux]# ulimit -a
core file size          (blocks, -c) 0  #0代表没有限制
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited  #可建立的单一文件大小
pending signals                 (-i) 14989
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024   #同时可以开启的文件数量
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 14989
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[root@localhost linux]# ulimit -f 10240
[root@localhost linux]# ulimit -a | grep 'file size'
core file size          (blocks, -c) 0
file size               (blocks, -f) 10240
[root@localhost linux]# dd if=/dev/zero of=123 bs=1M count=20
文件大小超出限制

10.2.8 变量内容的删除、取代与替换

变量内容的删除
变量设置方式说明
${变量#关键词}若变量内容从头开始的数据符合【关键词】,则将符合的最短数据删除
${变量##关键词}若变量内容从头开始的数据符合【关键词】,则将符合的最长数据删除
${变量%关键词}若变量内容从尾向前的数据符合【关键词】,则将符合的最短数据删除
${变量%%关键词}若变量内容从尾向前的数据符合【关键词】,则将符合的最长数据删除
${变量/旧字符串/新字符串}若变量内容符合【旧字符串】则第一个旧字符串会被新字符串替代
${变量//旧字符串/新字符串}若变量内容符合【旧字符串】则所有旧字符串会被新字符串替代

变量的测试与内容替换

10.3命令别名与历史命令

10.3.1 命令别名设置

10.3.2 历史命令【history】

10.4. Bash shell的操作环境

10.4.1 路径与命令查找顺序

1、以相对/绝对路径执行命令,例如【/bin.ls】或【./ls】

2、由alias找到该命令执行

3、由bash内置的(builtin)命令来执行

4、通过$PATH这个变量的顺序找到的第一个命令来执行

10.4.2 bash的登录与欢迎信息

/etc/issue:记录bash欢迎界面信息

[root@localhost linux]# cat /etc/issue
\S
Kernel \r on an \m
[root@localhost linux]# cat /etc/issue.net  #放置远程登陆的欢迎界面的配置文件
\S
Kernel \r on an \m

10.4.3 bash的环境配置文件

login shell取得shell时需要完整的登录流程,需要输入用户的账号密码。一般而言login shell只会读取以下两个文件:

/etc/profile:系统的整体配置,个人最好不要修改

~/.bash_profile 或~/.bash_login或 ~/.profile 属于用户个人设置,要添加个人数据,就写进这里。
non-login shell取得shell时不需要登陆操作。
/etc/profile只有login shll才会都,主要包含PATH、MAIL、USER、HOSTNAME、umask
/etc/profile.d/*.sh用户能够具有r权限,那么该文件就会被/etc/profile调用,
/etc/locale.conf决定bash默认使用何种语系,最重要的是LANG/LC_ALL变量的设置
/usr/share/bash-completion/completions/*可以进行命令参数的补全
~/.bashrcnon_login shell会读
/etc/man_db.conf规范了使用man的使用,man page的路径到哪里去寻找
~/.bash_history默认情况下历史命令就记录在这里
~/.bash_logout记录了“当我注销bash后,系统再帮我做完什么操作才离开”
[zyg@localhost ~]$ cat /etc/profile 
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in  #根据UID决定PATH要不要包含sbin
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}


if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"  #根据账号设置好用户的mailbox到var/spool/mail/账号名
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL  #将以上变量扩展为该bash的环境变量

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002  #root默认为022,一般用户默认为002
else
    umask 022
fi

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

[zyg@localhost ~]$ cat ~/.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then  #主动调用/etc/bashrc,由该文件定义不同UID设置的umask及提示字符
	. /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

10.4.4 终端的环境设置:【stty】、【set】

【stty -a】:查看当前所有按键的内容。

[root@localhost zyg]# stty -a
speed 38400 baud; rows 42; columns 168; line = 0;
intr = ^C; #发送一个interrupt(中断)的信号给目前正在run的程序
quit = ^\;   #发送一个quit给当前正在run的程序
erase = ^?;  #向后删除字符
kill = ^U;   #删除在目前命令上的所有文字
eof = ^D;    #End of file,代表结束输入
eol = <undef>;  #End of line,代表结束输入
eol2 = <undef>; 
swtch = <undef>; 
start = ^Q;   #在某个程序结束后,重新启动他的output
stop = ^S;    #停止目前屏幕的输出
susp = ^Z;    #发送一个terminial stop信号给正在运行的程序
rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

【set】可以设置整个命令输入/输出的环境,例如记录历史命令、显示错误内容。

-u默认不启用,启用后,当使用未设置变量时,会显示错误信息
-v默认不启用,启用后,在信息被输出前,会先显示信息的原始内容
-x默认不启用,启用后,在命令被执行前,会显示命令内容(前面有++符号)
-h默认启用,与历史命令有关
-H默认启用,与历史命令有关
-m默认启用,与任务管理有关
-B默认启用,与中括号[ ]的作用有关
-C默认不启用,若使用>等,则若文件存在时,该文件不会被覆盖
[root@localhost ~]# echo $-
himBH
[root@localhost ~]# echo $vbirding #默认情况下,未被设置变量打印为空

[root@localhost ~]# set -u
[root@localhost ~]# echo $vbirding #设置-u后,会提示错误信息
bash: vbirding: 为绑定变量
[root@localhost ~]# set -x
++ printf '\033]0;%s@%s:%s\007' zyg localhost '~'
[root@localhost ~]# ls
+ ls --color=auto  #输出的命令会被先打在屏幕上
anaconda-ks.cfg  linux  shell
++ printf '\033]0;%s@%s:%s\007' zyg localhost '~'

10.4.5 通配符与特殊符号

常用通配符

符号意义
*代表【0个到无穷多个】任意字符
?代表【一定会一个】任意字符
[ ]代表【一定有一个在括号内】的字符(非任意字符)
[ - ]代表【在编码顺序内的所有字符】,如[0-9]代表0到9之间的所有数字
[^]若中括号内的第一个字符为^则表示【反向选择】,即除括号内的其他字符就接受
[root@localhost conf.d]# ll -d /etc/cron* #找到该目录下以cron开头的目录
drwxr-xr-x. 2 root root  21 Feb 12 21:00 /etc/cron.d
drwxr-xr-x. 2 root root  55 Feb 12 21:14 /etc/cron.daily
-rw-------. 1 root root   0 Jan 14  2022 /etc/cron.deny
drwxr-xr-x. 2 root root  22 Feb 12 21:00 /etc/cron.hourly
drwxr-xr-x. 2 root root   6 Jun 10  2014 /etc/cron.monthly
drwxr-xr-x. 2 root root   6 Jun 10  2014 /etc/cron.weekly
-rw-r--r--. 1 root root 451 Jun 10  2014 /etc/crontab
[root@localhost conf.d]# ll -d /etc/?????  #找到该目录下五个字符长度的目录
drwxr-x---. 3 root root   83 Feb 12 20:57 /etc/audit
-rw-r--r--. 1 root root  465 Feb 12 20:55 /etc/fstab
drwxr-xr-x. 2 root root    6 Jul 13  2018 /etc/gnupg
drwxr-xr-x. 4 root root   40 Feb 12 20:55 /etc/groff
……
[root@localhost conf.d]# ll -d /etc/*[0-9]*  #找到该目录下包含数字的目录
-rw-r--r--. 1 root root 5725 Nov 16  2020 /etc/DIR_COLORS.256color
drwxr-xr-x. 5 root root   57 Feb 12 20:55 /etc/X11
drwxr-xr-x. 4 root root   78 Feb 12 20:55 /etc/dbus-1
……
[root@localhost conf.d]# ll -d /etc/[^a-z]*  #找到该目录下不含小写字母的目录
-rw-r--r--. 1 root root 5090 Nov 16  2020 /etc/DIR_COLORS
-rw-r--r--. 1 root root 5725 Nov 16  2020 /etc/DIR_COLORS.256color
-rw-r--r--. 1 root root 4669 Nov 16  2020 /etc/DIR_COLORS.lightbgcolor
-rw-r--r--. 1 root root   94 Mar 25  2017 /etc/GREP_COLORS
drwxr-xr-x. 7 root root  134 Jun 10  2021 /etc/NetworkManager
drwxr-xr-x. 5 root root   57 Feb 12 20:55 /etc/X11

特殊字符

符号内容
#注释符号:这个最常被使用在脚本当中,视为说明,在后的数据均不执行
\转义符:将【特殊字符或通配符】还原为一般字符
|管道:分隔两个管道命令的符号
;连续命令执行分隔符:连续性命令的定界
~用户的家目录
$使用变量前导符:亦即是变量之前需要加的变量替换值
&任务管理:将命令变为后台任务
!逻辑非
/目录符号:路径分隔的符号
>、>>数据流重定向:输出定向,分别是【替换】与【累加】
<、<<数据流重定向:输入定向
‘ ’单引号,不具有变量替换的功能
“ ”双引号,具有变量替换的功能,$可保留相关功能
` `两个【`】之间为可执行的命令,亦可使用$( )
( )在中间为子shell的起始与结束
{ }在中间为命令区块的组合

10.5 数据流重定向

10.5.1 什么是数据流重定向

不管正确或错误的数据都是默认输出到屏幕上,所以屏幕当然是乱的,那么就需要通过某些机制将多个数据流分开,即数据流重定向,数据流重定向可以将stdout、stderr分别传送到其他的文件或设备,而分别传送所用的特殊字符如下表示:

标准输入代码为0,使用 < 或 <<
标准输出代码为1,使用 > 或 >>
标准错误输出代码为2,使用2> 或 2>>

在重定向输出的文件中,若目标文件不存在,则会自动新建,若文件存在,若使用>重定向则会覆盖,>>则会将数据追加到文件的末尾。

[zyg@localhost ~]$ find /home/ -name .bashrc > list 2>&1 #将错误信息也按照标准输出写入list文件
[zyg@localhost ~]$ cat list 
/home/zyg/.bashrc
find: '/home/zyg1': Permission denied
[zyg@localhost ~]$ cat > catfile << "eof"  #将标准输入重定向到catfile,直到eof,相当于新建一个catfile文件。
> hello world!
> this is catfile
> eof
[zyg@localhost ~]$ cat catfile 
hello world!
this is catfile

/dev/null 垃圾桶黑洞设备与特殊写法,所有被写入此文件的数据都将被丢弃。

10.5.2 命令执行的判断依据

;不考虑命令相关性的连续执行命令
&&前一个命令正确执行才执行后一个命令
|若前一个命令不能正确执行才执行后一个命令

10.6 管道命令

在每个管道后面接的第一个数据必定是【命令】,而且这个命令必须能够接受标准输入的数据才行,这样的命令被称为管道命令。

注:管道命令仅会处理标准输出,对于标准错误会予以忽略;管道命令必须能够接受来自前一个命令的数据成为标准输入继续处理才行。

10.6.1 选取命令:【cut】、【grep】

【cut】将一段信息的某一段切出来,处理的信息是以行为单位的

-d后面接分隔字符,配合-f一起使用
-f根据-d的分隔字符将一段信息划分成数段,用-f取出第几段
-c以字符的单位取出固定字符区间
[root@localhost ~]# echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# echo ${PATH} | cut -d ':' -f 3,5
/usr/sbin:/root/bin
[root@localhost ~]# echo ${PATH} | cut -c 16-
:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

【grep】分析一行信息,若当中有我们所需要的信息,则提取出来

-a将二进制文件以文本文件的方式查找数据
-c计算找到查找字符的次数
-i忽略大小写的不同
-n顺便输出行号
-v反向选择,亦即显示出没有查找字符的那一行
[root@localhost ~]# last | grep -v root | cut -d ' ' -f 1,8,9,10,11
reboot Thu Feb 23 10:00
reboot Wed Feb 22 20:06
reboot Tue Feb 21 17:57
reboot Sat Feb 18 21:02
reboot Sat Feb 18 20:59
reboot Sat Feb 18 20:39
reboot Sat Feb 18 19:29
reboot Thu Feb 16 13:01
reboot Mon Feb 13 21:30
reboot Mon Feb 13 07:48
reboot Sun Feb 12 22:58
reboot Sun Feb 12 22:56
zyg    
reboot Sun Feb 12 20:57

10.6.2 排序命令:【sort】、【wc】、【uniq】

【sort】根据不同的数据形式来排序,排序的字符与语系的编码有关。

-f忽略大小写的差异,例如A与a视为编码相同
-b忽略最前面的空格字符部分
-M以月份的名称来排序
-n使用纯数字进行排序
-r反向排序
-u就是uniq,相同的数据,仅出现一行代表
-t分隔符号,默认以[tab]进行分隔
-k以那个区间来进行排序
[root@localhost ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
……
[root@localhost init.d]# cat /etc/passwd | sort -t ':' -k 3 #以:分隔,按第三栏排序
……
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
……
[root@localhost ~]# last | cut -d ' ' -f 1 | sort -u

reboot
root
wtmp
zyg

【uniq】将重复的数据仅列出一个显示

-i忽略大小写字符的不同
-c进行计数
[root@localhost ~]# last | cut -d ' ' -f 1 | sort | uniq -ic
      1 
     14 reboot
     25 root
      1 wtmp
      1 zyg

【wc】计算输出信息的整体数据

-l仅列出列
-w仅列出多少词(英文字母)
-m仅列出多少字符
[root@localhost ~]# last | cut -d ' ' -f 1 | wc  #以下三个字母分别代表共多少行、多少词、多少字符
     42      41     233
[root@localhost ~]# last | cut -d ' ' -f 1 | grep -v reboot | grep -v wtmp | grep -v 'unknown' | wc -l
27

10.6.3 双向重定向 【tee】

【tee】同时将数据流分送到文件和屏幕,而输出到屏幕的其实就是stdout

-a以累加的方式,将数据加入file当中
[root@localhost linux]# last | tee last.list | cut -d " " -f 1 | sort  | uniq -c
      1 
     14 reboot
     25 root
      1 wtmp
      1 zyg
[root@localhost linux]# cat last.list 
root     pts/0        192.168.10.7     Fri Feb 24 11:32   still logged in   
reboot   system boot  3.10.0-1160.83.1 Fri Feb 24 11:13 - 12:04  (00:50)    
root     pts/0        192.168.10.7     Fri Feb 24 10:52 - crash  (00:21)    
root     pts/0        192.168.10.10    Thu Feb 23 10:37 - 23:36  (12:58)    
root     tty1                          Thu Feb 23 10:16 - crash (1+00:57)   
reboot   system boot  3.10.0-1160.83.1 Thu Feb 23 10:00 - 12:04 (1+02:03)   
……

10.6.4 字符转换命令:【tr】、【col】、【join】、【paste】、【expand】

【tr】用来删除一段信息当中的文字,或是进行文字信息的替换

-d删除信息当中的SET1这个字符
-s替换掉重复的字符
[root@localhost linux]# last | tr '[a-z]' '[A-Z]' #将所有的小写字符变成大写字符
ROOT     PTS/0        192.168.10.7     FRI FEB 24 11:32   STILL LOGGED IN   
REBOOT   SYSTEM BOOT  3.10.0-1160.83.1 FRI FEB 24 11:13 - 12:12  (00:59)    
ROOT     PTS/0        192.168.10.7     FRI FEB 24 10:52 - CRASH  (00:21)    
ROOT     PTS/0        192.168.10.10    THU FEB 23 10:37 - 23:36  (12:58)    
ROOT     TTY1                          THU FEB 23 10:16 - CRASH (1+00:57)   
[root@localhost linux]# last | tr -d ' ' #将所有的空格删除
rootpts/0192.168.10.7FriFeb2411:32stillloggedin
rebootsystemboot3.10.0-1160.83.1FriFeb2411:13-12:15(01:02)
rootpts/0192.168.10.7FriFeb2410:52-crash(00:21)
rootpts/0192.168.10.10ThuFeb2310:37-23:36(12:58)

【col】很多时候用来简单地将[tab]替换成等长的空格

-x将tab键替换成对等的空格键
[root@localhost linux]# cat /etc/man_db.conf |cat -A  #^I就是tab键
# $
#$
# This file is used by the man-db package to configure the man and cat paths.$
# It is also used to provide a manpath for those without one by examining$
# their PATH environment variable. For details see the manpath(5) man page.$
#$
# Lines beginning with `#' are comments and are ignored. Any combination of$
# tabs or spaces may be used as `whitespace' separators.$
#$
# There are three mappings allowed in this file:$
# --------------------------------------------------------$
# MANDATORY_MANPATH^I^I^Imanpath_element$
# MANPATH_MAP^I^Ipath_element^Imanpath_element$
# MANDB_MAP^I^Iglobal_manpath^I[relative_catpath]$
#---------------------------------------------------------$
# every automatically generated MANPATH includes these fields$
#$
#MANDATORY_MANPATH ^I^I^I/usr/src/pvm3/man$
#$
MANDATORY_MANPATH^I^I^I/usr/man$
MANDATORY_MANPATH^I^I^I/usr/share/man$
MANDATORY_MANPATH^I^I^I/usr/local/share/man$
#---------------------------------------------------------$


[root@localhost linux]# cat /etc/man_db.conf |col -x |cat -A  #已经将诸多^I替换成了空格,看起来美观了许多
#$
#$
# This file is used by the man-db package to configure the man and cat paths.$
# It is also used to provide a manpath for those without one by examining$
# their PATH environment variable. For details see the manpath(5) man page.$
#$
# Lines beginning with `#' are comments and are ignored. Any combination of$
# tabs or spaces may be used as `whitespace' separators.$
#$
# There are three mappings allowed in this file:$
# --------------------------------------------------------$
# MANDATORY_MANPATH                     manpath_element$
# MANPATH_MAP           path_element    manpath_element$
# MANDB_MAP             global_manpath  [relative_catpath]$
#---------------------------------------------------------$
# every automatically generated MANPATH includes these fields$
#$
#MANDATORY_MANPATH                      /usr/src/pvm3/man$
#$
MANDATORY_MANPATH                       /usr/man$
MANDATORY_MANPATH                       /usr/share/man$
MANDATORY_MANPATH                       /usr/local/share/man$
#---------------------------------------------------------$

【join】在处理两个文件之间的数据,且主要是在住了两个文件当中,有相同数据的那一行才将它加在一起。需要注意的是,比对之前需要将待处理的文件进行排序,否则就有可能将某些比对项目忽略掉。

-tjoin默认以空格字符分隔数据,并且比对【第一个栏位】的数据。

如果两个文件相同,则将两条数据连成一行,且第一个栏位放在第一个
-i忽略大小写差异
-1数字1,代表第一个文件要用在哪个栏位来分析
-2数字2,代表第二个文件要用在哪个栏位来分析
[root@localhost linux]# 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$Y2iT8kmF$QN3pa6eSSdH9LcyMFMtYiXyq73Su91ybnX.hRB9LUuPEufgiuyrVQ6CLR6pF2iA0zNoZ6hJ5NcFfX/6qTaqU60:19400:0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::

[root@localhost linux]# join -t ':' /etc/passwd /etc/shadow | head -n 3 #利用join把二者合一
root:x:0:0:root:/root:/bin/bash:$6$Y2iT8kmF$QN3pa6eSSdH9LcyMFMtYiXyq73Su91ybnX.hRB9LUuPEufgiuyrVQ6CLR6pF2iA0zNoZ6hJ5NcFfX/6qTaqU60:19400:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:18353:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18353:0:99999:7:::

【paste】比join更粗暴,直接将两行贴在一起,以[tab]隔开。

-d接分隔符,默认是[tab]
-如果file部分写成 - ,表示来自标准输入的数据
[root@localhost linux]# cat /etc/group |paste  /etc/passwd /etc/shadow - | head -n 3 #注意此案例中的 - 
root:x:0:0:root:/root:/bin/bash	root:$6$Y2iT8kmF$QN3pa6eSSdH9LcyMFMtYiXyq73Su91ybnX.hRB9LUuPEufgiuyrVQ6CLR6pF2iA0zNoZ6hJ5NcFfX/6qTaqU60:19400:0:99999:7:::	root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin	bin:*:18353:0:99999:7:::	bin:x:1:
daemon:x:2:2:daemon:/sbin:/sbin/nologin	daemon:*:18353:0:99999:7:::	daemon:x:2:

【expand】将[tab]按键转成空格键

-t后面可接数字,一般来说一个tab可以用8个空格表示,我们也可以自定义其用几个空格表示。
[root@localhost linux]# grep '^MANPATH' /etc/man_db.conf | head -n 3
MANPATH_MAP	/bin			/usr/share/man
MANPATH_MAP	/usr/bin		/usr/share/man
MANPATH_MAP	/sbin			/usr/share/man
[root@localhost linux]# grep '^MANPATH' /etc/man_db.conf | head -n 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$
[root@localhost linux]# grep '^MANPATH' /etc/man_db.conf | head -n 3 |expand -t 8| cat -A
MANPATH_MAP     /bin                    /usr/share/man$
MANPATH_MAP     /usr/bin                /usr/share/man$
MANPATH_MAP     /sbin                   /usr/share/man$

【split】将一个大文件依据文件大小或行数来划分成小文件。

-b按文件大小来划分,可以接单位b、k、m
-l以行数来划分
[root@localhost linux]# ll -h
总用量 9.6M
-rw-r--r--. 1 root root 3.1K 2月  24 12:04 last.list
drwxr-xr-x. 2 root root  106 2月  24 16:52 split_test
-rw-r--r--. 1 root root 9.6M 2月  24 16:49 test.txt
[root@localhost linux]# split -b 1m test.txt ./split_test/
[root@localhost split_test]# ll -h
总用量 9.6M
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 aa
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ab
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ac
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ad
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ae
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 af
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ag
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ah
-rw-r--r--. 1 root root 1.0M 2月  24 16:52 ai
-rw-r--r--. 1 root root 550K 2月  24 16:52 aj

【xargs】参数代换,该命令可以读入stdin的数据,并且以空格符或换行符作为识别符,将stdin的数据分割成为参数。当xargs后面不接参数时,默认是以echo来进行输出。

-0如果输入的stdin含有特殊字符,例如`、\ 、空格等字符时,该参数可以将它还原为一般字符,这个参数可用于特殊状态
-e即EOF,后面可以接一个字符,当xargs分析到这个字符时,就会停止工作
-p在执行每个命令时,都会询问使用者意思
-n后面接次数,每次com命令执行时,要使用几个参数的意思
[root@localhost linux]# cut -d ':' -f1 /etc/passwd | head -n 3
root
bin
daemon

[root@localhost linux]# cut -d ':' -f1 /etc/passwd | head -n 3 | xargs -n 1 id
uid=0(root) gid=0(root) 组=0(root)
uid=1(bin) gid=1(bin) 组=1(bin)
uid=2(daemon) gid=2(daemon) 组=2(daemon)
[root@localhost linux]# cut -d ':' -f1 /etc/passwd | head -n 3 | xargs -pn 1 id
id root ?...y
id bin ?...uid=0(root) gid=0(root) 组=0(root)
y
id daemon ?...uid=1(bin) gid=1(bin) 组=1(bin)
y
uid=2(daemon) gid=2(daemon) 组=2(daemon)
[root@localhost linux]# cut -d ':' -f1 /etc/passwd | xargs -e'sync' -n 1 id
uid=0(root) gid=0(root) 组=0(root)
uid=1(bin) gid=1(bin) 组=1(bin)
uid=2(daemon) gid=2(daemon) 组=2(daemon)
uid=3(adm) gid=4(adm) 组=4(adm)
uid=4(lp) gid=7(lp) 组=7(lp)

【-】关于减号的用途:在某些管道命令需要用到文件名来处理时,该stdin与stdout可以用" - "来替代。

 类似资料: