[Linux Shell学习系列二]初识Linux Shell
D4
(本章采用bash)
1. Shell在Linux环境中的角色?
Shell在Linux环境中扮演了非常重要的角色,包括读取命令行、解释它的含义并执行、通过输出返回执行结果等。
2. 与登录Shell相关的文件有哪些?
/etc/profile——系统级的初始化文件,定义了一些环境变量,由登录Shell调用执行;。
/etc/bash.bashrc或/etc/bashrc——不同Linux版本采用的文件名不同,每个交互式Shell的系统级的启动脚本,定义了一些函数和别名。
/etc/bash.logout——系统级的登录Shell清理脚本,登陆Shell退出时执行。部分Linux发行版默认是没有此文件。
$HOME/.bash_profile、$HOME/.bash_login、$HOME/.profile——用户个人初始化脚本,由登录Shell调用执行。按照此顺序查找,只有第一个存在的被执行。
$HOME/.bashrc——用户个人的每个交互式Shell的启动脚本。
$HOME/.bash_logout——用户个人的登录Shell清理脚本,登陆Shell退出时执行。
$HOME/.inputrc——用户个人的由readline使用的启动脚本,定义了处理某些情况下的键盘映射。
D5
3. 用户登录时,登录Shell会执行哪些脚本?
登录Shell是登录系统时最先执行的Shell,它设置一些环境(通过调用脚本),然后把这些环境授予非登录Shell。
用户登录时,登录Shell会调用如下脚本:
/etc/profile——当用户在运行级别3登录系统时首先运行。
/etc/profile.d——当/etc/profile运行时,会调用该目录下的一些脚本。
$HOME/.bash_profile、$HOME/.bash_login、$HOME/.profile——在/etc/profile运行后,第一个存在的被运行。
$HOME/.bashrc——上述脚本中的一个运行后即调用此脚本。
/etc/bashrc或/etc/bash.bashrc——由$HOME/.bashrc调用运行。
4. 当一个交互式的非登录Shell启动时,Bash将读取并运行哪些脚本?
$HOME/.bashrc——如果此文件存在即被运行。
/etc/bashrc——将被$HOME/.bashrc调用运行。
/etc/profile.d——此目录下的脚本将被/etc/bashrc或/etc/bash.bashrc调用运行。
5. Bash启动脚本主要设置的环境有哪些?
设置环境变量PATH和PSI;
通过变量EDITOR设置默认的文本编辑器;
设置默认的umask(文件或目录的权限属性);
覆盖或移除不想要的变量或别名;
设置别名;
加载函数。
6. 登录Shell退出时运行哪些脚本?
如果$HOME/.bash_logout脚本存在,Bash会读取并执行此脚本的内容。该脚本主要有以下用途:
使用clear命令清理你的终端屏幕输出;
移除一些临时文件;
自动运行一些命令或脚本等。
7. 如何查看登录Shell的路径?
1)查看/etc/shells文件
2)使用which命令:
which bash
8. Shell中变量的类型有哪些?
1)系统变量(环境变量):由Linux Bash Shell创建和维护的变量。
2)用户自定义的变量(本地变量或Shell变量)。
9. 常用的系统变量有哪些?
| 系统变量 | 含义 |
| BASH_VERSION | 保存Bash实例的版本 |
| DISPLAY | 设置X display的名字 |
| EDITOR | 设置默认的文本编辑器 |
| HISTFILE | 保存命令历史的文件名 |
| HISTFILESIZE | 命令历史文件所能包含的最大行数 |
| HISTSIZE | 记录在命令历史中的命令数 |
| HOME | 当前用户的主目录 |
| HOSTNAME | 你的计算机的主机名 |
| IFS | 定义Shell的内部字段分隔符,一般是空格符、制表符和换行符 |
| PATH | 搜索命令的路径,以冒号分割的目录列表 |
| PS1 | 你的提示符设定 |
| PWD | 当前工作目录,由cd命令设置 |
| SHELL | 设置登录Shell的路径 |
| TERM | 设置你的登录终端的类型 |
| TMOUT |
用于设置Shell内建命令read的默认超时时间(秒), 交互式Shell中,该时间为发出命令后等待用户输入的秒数,如果没有用户输入会自动退出 |
10. 如何设置系统变量?
添加上述变量到你帐号的home目录下的初始化文件中,如~/.bash_profile。
这样你每次登录系统时,这些变量会自动设置为你需要的值。
11. 如何查看当前Shell的所有系统变量?
1) 命令:env
2) 命令:printenv
12. 如何查看当前Shell中所有用户自定义变量和系统变量?
命令:env
D6
13. 如何定义变量和给变量赋值?
varName=varValue 依次是:变量名、赋值操作符=、赋予的值
注意:=左右不能有空格
$ a=zifuchuan #字符集合 $ b="zifuchuan" #字符集合 $ c=1 #数字 $ d=$c+1 #注意shell的默认赋值是字符串赋值 $ echo d 1+1 $ let e=2+1 #算数表达式赋值用let $ echo e 3 $ f=$e #另一个变量的值 $ g=`pwd` #命令的执行结果 $ h=$(pwd) #命令的执行结果的另外一种形式
#将read读取的内容赋值给变量
$echo -n "Enter i"; read i #打印内容Enter i且不换行,紧接着从标准输入读入内容
Enter i: 123 #此处用户输入123并回车,则将123赋值给i
$echo $i
123
14. 变量命名规则有哪些?
变量必须以字母或下划线字符“_”开头,后面跟字母、数字或下划线字符,第一个字符不能为数字。
不要使用?、*和其他特殊字符命名你的变量。
15.如何打印变量的值?
1)echo命令:
没有格式化选项,简单输出
也提供转义字符,但需要用-e选项激活转义字符功能
echo -e "Username: $USER\tHome: $HOME\n"
必要时需使用${}避免歧义
$ LOGDIR="/var/log/" $ echo "The log file is $LOGDIRmessages" The log file is #有歧义,bash会寻找LOGDIRmessages变量而不是LOGDIR,没有找到而输出空 $ echo "The log file is ${LOGDIR}messages" The log file is /var/log/messages #正确的输出
2)printf命令:类似于C函数中系统接口printf()的打印格式化文本的方法。
printf <FORMAT> <ARGUMENTS> #根据指定的格式FORMAT打印ARGUMENTS的内容
printf "FirstName: %s\nLastName: %s" "$FirstName" "$LastName" #%s是格式类型的分类符,\n是转义字符,表示换行
注:分类符和转移字符有很多,这里不列出
16. 如何引用变量?
引用单个变量:“$var” #可以防止变量值中的特殊字符被解释为其他错误含义(不包括$、'和\)
双引号会忽略变量值中的空格等,如
$ LIST="one two three" $ for var in $LIST #变量LIST的值分成3个参数传递给for循环 > do > echo "$var" > done one two three $ for var in "$LIST" #变量LIST的值作为一个整体传递给for循环 > do > echo "$var" > done one two three
单引号不允许引用变量,因为在单引号中除了',其他特殊字符都会按字面含义解释($的特殊含义也失效)。
17. 如何使用export语句?
运行shell脚本时,系统将创建一个子Shell,当此Shell脚本运行完毕时,这个子Shell将终止,环境将返回到该脚本运行之前的Shell。
默认情况下,用户定义的变量只在当前Shell有效,不能被后续的Shell引用。
export命令将变量输出,使其可以被子Shell引用。
语法:export [-fnp] [变量或函数名称]=[变量设置值]
-f:表示export一个函数;
-n:表示将export属性从指定变量或函数上移除;
-p:打印当前Shell所有输出的变量,与单独执行export命令结果相同。
示例:
$ echo $JAVA_HOME /usr/local/jdk #运行一个新的子Shell $ bash bash-3.2$ echo $JAVA_HOME #此处输出为空行 bash-3.2$ exit #退出子Shell exit #运行export命令 $ export JAVA_HOME #重新运行一个新的子Shell $ bash bash-3.2$ echo $JAVA_HOME #此处输出值 /usr/local/jdk #继续运行新的子Shell,变量JAVA_HOME仍然有效 bash-3.2$ exit #退出子Shell exit
18. 如何删除变量?
unset命令,会把变量从当前Shell和后续命令的环境中删除。
unset [-fv] [变量或函数名称]
bash-3.2$ JAVA_HOME=/usr/local/jdk #变量 bash-3.2$ echo $JAVA_HOME /usr/local/jdk bash-3.2$ unset JAVA_HOME #删除变量 bash-3.2$ echo $JAVA_HOME #输出空 bash-3.2$ readonly JAVA_HOME=/usr/local/jdk #只读变量 bash-3.2$ echo $JAVA_HOME /usr/local/jdk bash-3.2$ unset JAVA_HOME #不能删除只读变量 bash: unset: JAVA_HOME: cannot unset: readonly variable
19. 如何检查变量是否存在?
1)采用语句:${varname? Error: The variable is not defined}
#如果varname已定义且不为空,输出同$varname,如: $ varname="aaa" $ ${varname? Error: The variable is not defined} bash: aaa: command not found $ echo ${varname? Error: The variable is not defined} aaa #如果varname的值是空,输出空: $ varname= $ ${varname? Error: The variable is not defined} #如果varname是未定义的,输出信息: ${varname? Error: The variable is not defined} bash: varname: Error: The variable is not defined
2)采用语句:${varname:? Error: The variable is not defined} #与上面的区别是空值的判断
#如果varname已定义且不为空,输出同$varname,如: $ varname="aaa" $ ${varname:? Error: The variable is not defined} bash: aaa: command not found $ echo ${varname:? Error: The variable is not defined} aaa #如果varname的值是空,输出信息: $ varname= $ ${varname:? Error: The variable is not defined} bash: varname: Error: The variable is not defined $ echo ${varname:? Error: The variable is not defined} bash: varname: Error: The variable is not defined #如果varname是未定义的,输出信息: ${varname:? Error: The variable is not defined} bash: varname: Error: The variable is not defined $ echo ${varname:? Error: The variable is not defined} bash: varname: Error: The variable is not defined
3)更常用的是用if语句判断变量是否存在,在后面章节中详细介绍。
20. 如何查看命令历史?
bash将命令历史保存在缓冲区或默认文件~/.bash_history中。命令缓冲区保存命令的多少由环境变量HISTSIZE定义。
1)history命令:显示你在命令行提示符下输入的命令列表;可以显示历史命令列表的行号。
2)可以在命令提示符下使用↑和↓方向键找到之前执行过的命令。
3)在命令行提示符下使用Ctrl+r组合键后输入相应的关键字可以搜索历史命令。
4)在Shell命令行提示符下简单的输入!!来重复执行上一条执行过的命令。
$ echo $$ 30579 $ !! echo $$
30579
5)用!+指定字符回调最近一次执行的以指定字符开头的命令。
$ echo $$ 30579 $ !e echo $$ 30579
6)用!+history列出的命令列表行号来重新调用命令。
$ history 1 pwd ... 10 echo $$ 11 history $ !10 echo $$ 30579
21. Shell中有哪些扩展的方式?
共有8种:(按扩展的先后顺序排序)大括号扩展、波浪号扩展、参数和变量扩展(后续介绍)、命令替换、算数扩展(后续介绍)、进程替换(依赖操作系统的支持,不做介绍)、单词拆分和文件名扩展。
22. 大括号扩展
大括号扩展是一种能够生成任意字符串的机制。
模式:一个可选的前缀+一组包含在大括号内用逗号分隔的字符串或序列表达式+一个可选的后缀。
$ echo a{b,c,d}e abe ace ade $ echo {a..f} #按字母序显示a到f a b c d e f $ echo {0..10} #按顺序显示0到10 0 1 2 3 4 5 6 7 8 9 10 $ echo {5..-3} #按顺序显示5到-3 5 4 3 2 1 0 -1 -2 -3 $ echo {1..3}{c..a} #组合 1c 1b 1a 2c 2b 2a 3c 3b 3a
1)可以是嵌套的
$ echo a{{b,c,d}e,{f,g,h}i}j #不会进行排序,按照从左到右顺序进行扩展 abej acej adej afij agij ahij
2)可以与其他命令配合使用
$ mkdir ./{a,b} #在当前目录下创建a和b文件夹 $ ls a b
3)大括号扩展在所有其他扩展之前进行:
在其他扩展中的特殊符号都被保留下来。{或,或}需要用\转义。
大括号扩展不会识别字符串中的${,以避免与参数扩展冲突。
23. 波浪号扩展
波浪号扩展的用法:
1)可用来指代自己或他人的主目录
$ cd ~ #user1用户自己的主目录 $ pwd /home/user1 $ cd ~user2 #user2用户的主目录 $ pwd /home/user2
一个单词以未被引用的~开头,则直到第一个未被引用的/中所有字符被看做波浪号前缀。
如果波浪号前缀中字符都没有被引用,则波浪号后面的所有字符被看做一个可能存在的登录用户名:
该用户名为空,被替换成Shell变量HOME的值;若没有设置HOME,则替换成执行该命令的用户的主目录;
否则替换成指定的登录用户名的主目录。
2) ~+:被Shell变量PWD替代(如果设置了该变量)
$ echo ~+ /home/ntrade $ echo $PWD /home/ntrade
3)~-:被Shell变量的OLDPWD替代(如果设置了该变量)
$ echo ~- /home/ntrade $ echo $OLDPWD /home/ntrade
23. 命令替换
命令替换是用命令的输出替换命令本身,有两种形式:${COMMAND}或`COMMAND`
bash进行命令替换时,会先执行命令,然后用命令的标准输出结果取代命令替换,命令的标准输出结果中最后的换行符会被删除。
$ date Mon May 11 17:19:58 CST 2020 $ echo $(date) Mon May 11 17:20:24 CST 2020 $ echo `date` Mon May 11 17:20:35 CST 2020
命令替换可以嵌套
$ echo "The date is: `echo $(date)`" #外层使用``,内层使用$() The date is: Mon May 11 15:26:30 CST 2020 $ echo "The date is: $(echo $(date))" #外层使用$(),内层使用$() The date is: Mon May 11 15:26:50 CST 2020 $ echo "The date is: $(echo `date`)" #外层使用$(),内层使用`` The date is: Mon May 11 15:27:04 CST 2020 $ echo "The date is: `echo `date``" #使用两层``,但未转义 The date is: date $ echo "The date is: `echo \`date\``" #使用两层``,内层``需要转义 The date is: Mon May 11 15:26:15 CST 2020
24. 文件名扩展
Bash中没有设置-f选项,就会支持文件名扩展。Bash支持以下三种通配符来实现文件名扩展:
*——匹配任何字符串,包括空字符串;
?——匹配任意单个字符;
[...]——匹配方括号内任意字符。
$ ls -R #在该目录下执行下面的命令 a b ./a: test ./a/test: a.txt file1.txt file2.txt ./b: test ./b/test: b.txt file3.txt file4.txt file10.txt $ ls */test #列出所有目录下的test子目录下的文件 a/test: a.txt file1.txt file2.txt b/test: b.txt file3.txt file4.txt $ ls */test/[ab]*.txt #列出所有目录下test子目录下以a或b开头的txt文件,不会列出file0.txt等 a/test/a.txt b/test/b.txt $ ls */test/file?.txt #列出所有目录下test子目录下file+单个字符的txt文件,不会列出a.txt、file10.txt等 a/test/file1.txt a/test/file2.txt b/test/file3.txt b/test/file4.txt
25. 如何创建别名?
alias命令: alias name='command'
name——用户定义的用户别名的任意简短的名字
command——任意Linux命令
在命令行中执行,会创建临时的别名,仅在退出此Shell前有效;在~/.bashrc中添加,持久有效(添加后需重新登录才生效)。
$ ls -al total 16 drwxrwxr-x. 4 user1 user1 4096 May 11 14:58 . drwxr-xr-x. 33 user1 user1 4096 May 11 15:42 .. drwxrwxr-x. 3 user1 user1 4096 May 11 15:01 a drwxrwxr-x. 3 user1 user1 4096 May 11 15:01 b $ alias la='ls -al' #将la设置为别名 $ la total 16 drwxrwxr-x. 4 user1 user1 4096 May 11 14:58 . drwxr-xr-x. 33 user1 user1 4096 May 11 15:42 .. drwxrwxr-x. 3 user1 user1 4096 May 11 15:01 a drwxrwxr-x. 3 user1 user1 4096 May 11 15:01 b
$ alias #不带参数可列出当前环境下所有的别名 alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l.='ls -d .* --color=auto' alias la='ls -al' alias ll='ls -l --color=auto' alias ls='ls --color=auto' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
$ alias la #查看特定的别名 alias la='ls -al'
$ alias cp='cp -iv' $ cp c.txt d.txt 'c.txt' -> 'd.txt' $ cp e.txt d.txt #cp别名代表的命令cp -iv cp: overwrite 'd.txt'? $ \cp e.txt d.txt #临时使用正常的cp命令代替cp别名
$ unalias cp #删除别名cp $ cp e.txt d.txt #使用的是正常的cp命令
$ alias -a #删除当前环境下所有的别名 $ alias #查看所有别名,此时为空
注意:虽然别名的使用简单而方便,但要非常谨慎地使用别名替换标准命令。
26. 修改Bash提示符
设置环境变量PS1可以定制你自己的Bash提示符
$ echo $PS1 #显示当前提示符设置 [\u@\h \W]\$ # 上面的信息表示: # \u:用户名 # \h:主机名 # \W:当前工作目录去掉前导目录后的目录名,如果是\HOME代表的目录则用~代替 # \$:如果当前用户的UID=0则显示#,否则显示$
可以自己定制:
$ export PS1="[\t \u@\h \W]\$" #增加了时间\t [17:05:57 user1@192.168.1.100 dir1]$
注:有很多带反斜杠的特殊字符可以用于定制Bash提示符,此处不列出。
可以在提示符中显示命令的输出:
$export PS1="[`uname -r` \u@\h \W]\$" [4.4.0-62-generic user1@192.168.1.100 dir1]$
另外还可以配置颜色等,此处不列出。
如果想每次登录时自动设置你的Shell提示符,就需要将环境变量PS1放在你的~/.bashrc文件中,并使用export将其输出到其他子命令。
27. 如何使用set和shopt控制Bash的行为?
可以通过set和shopt开启或关闭Bash的相关选项控制Bash的行为,不同的选项使用不同的开启和关闭的方法。
set和shopt各控制一组选项。
1)set命令
$ set -o #使用-o不带选项可查看所有set命令控制的Bash选项及其当前状态 allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off $ set -o ignoreeof #使退出登录Shell的Ctrl+d按键失效 #此时尝试Ctrl+d Use "logout" to leave the shell. $ set +o ignoreeof #将此选项关闭 #可以用Ctrl+d退出Shell了
2)shopt命令
$ shopt #查看shopt控制的Bash选项机器状态 autocd off cdable_vars off cdspell off checkhash off checkjobs off checkwinsize on cmdhist on compat31 off compat32 off compat40 off compat41 off direxpand off dirspell off dotglob off execfail off expand_aliases on extdebug off extglob off extquote on failglob off force_fignore on globstar off gnu_errfmt off histappend on histreedit off histverify off hostcomplete on huponexit off interactive_comments on lastpipe off lithist off login_shell on mailwarn off no_empty_cmd_completion off nocaseglob off nocasematch off nullglob off progcomp on promptvars on restricted_shell off shift_verbose off sourcepath on syslog_history off xpg_echo off $ shopt -s feature-name #开启一个Bash选项 $ shopt -u feature-name #关闭一个Bash选项
注:上述选项的详细信息和示例此处不列出
3)定制Bash环境:
可以在你的~/.bashrc中添加shopt和set命令,为自己定制一个Bash环境;
可以定制系统范围的Bash环境,默认的Bash系统范围的用户参数文件是/etc/profile,可以强制所有用户使用这个文件。
在CentOS、Fedora和Redhat企业级Linux推荐使用目录/etc/profile.d文件。

浙公网安备 33010602011771号