zql@zql-PC:~$ type -a pwd
pwd 是 shell 内建
pwd 是 /usr/bin/pwd
pwd 是 /bin/pwd
zql@zql-PC:~$ type -a echo
echo 是 shell 内建
echo 是 /usr/bin/echo
echo 是 /bin/echo
zql@zql-PC:~$ type -a cd
cd 是 shell 内建
zql@zql-PC:~$
可以看见echo与pwd还有别的路径,他们不仅仅是shell内建命令。
注意:which只能看见外部命令
1.9.3 命令别名
查看当前系统可以使用的别名可以使用命令alias
-a 查看当前所有的可以使用的别名
例
# 进入子shell
zql@zql-PC:~$ bash
# 查看别名列表
zql@zql-PC:~$ alias -p
alias ls='ls --color=auto'
#退出子shell
zql@zql-PC:~$ exit
exit
#查看别名列表
zql@zql-PC:~$ alias -p
alias ll='ls -l'
alias ls='ls --color=auto'
设置别名
语法
alias 别名='命令'
例
zql@zql-PC:~$ alias l='ls -CF'
zql@zql-PC:~$ alias la='ls -A'
zql@zql-PC:~$ alias -p
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -l'
alias ls='ls --color=auto'
zql@zql-PC:~$ alias li='ls -i'
zql@zql-PC:~$ la
abc .config gcadlog hallo.sh Music .themes
.bash_history .deepin-themes .gtkrc-2.0 hallo.tar Pictures Videos
.bash_logout .deepinwine hallo.c hallo.txt .pki .vscode
.bashrc Desktop hallo.cpp .icons .profile .Xauthority
.cache .dmrc hallo.java .imwheelrc .Public .xsession-errors
code Documents hallo.md .linglong .sudo_as_admin_successful .xsession-errors.old
com.hmja.ccompare Downloads hallo.py .local .Templates
zql@zql-PC:~$ li
2621458 abc 2622349 Documents 2622032 hallo.cpp 2622002 hallo.sh 2622316 Pictures
2632317 code 2622348 Downloads 2622031 hallo.java 2622033 hallo.tar 2622350 Videos
2621748 com.hmja.ccompare 2631954 gcadlog 2622034 hallo.md 2622035 hallo.txt
2622363 Desktop 2622030 hallo.c 2622024 hallo.py 2622365 Music
注意:被定义的别名仅在当前的shell内有效,他是内建命令。
删除自己定义的别名
语法
unalias 别名
例
zql@zql-PC:~$ unalias li
zql@zql-PC:~$ li
-bash: li:未找到命令
zql@zql-PC:~$
zql@zql-PC:~$ cat /etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "$(id -u)" -eq 0 ]; then
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin"
fi
export PATH
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "$(id -u)" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
zql@zql-PC:~$
.$HOME/.bash_profile
.$HOME/.bashrc
.$HOME/.bash_login
.$HOME/.profile
zql@zql-PC:~$ cat $HOME/.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
#alias grep='grep --color=auto'
#alias fgrep='fgrep --color=auto'
#alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
# Set LS_COLORS environment by Deepin
if [[ ("$TERM" = *256color || "$TERM" = screen* || "$TERM" = xterm* ) && -f /etc/lscolor-256color ]]; then
eval $(dircolors -b /etc/lscolor-256color)
else
eval $(dircolors)
fi
zql@zql-PC:~$
版权授予:哔哩哔哩-TIANGESEC工作室、微信公众号-TIANGESEC工作室
联系作者:[email protected](QQ:1072441436)
错误反馈:请发邮箱[email protected],请使用Word将错误写下,并附上截图,放置在邮箱附件中,改写反馈。
优化建议:请发邮箱[email protected],请使用Word需要改进的地方写下,并附上截图;若有内容添加建议,请在word文件中表明,并放置在邮箱附件中,感谢建议。
基于deepin的shell编程 更新日志
版本号带有
Update
的表示为大体内容没有完成,持续更新中版本号带有
Release
的表示代替大体内容已经完成,待反馈和优化以及增加内容版本号里面带有
Alpha
的代表内容在修改中更新内容:1.1进程列表-2.9数组变量
更新内容:3shell运算符-11.7其他选项
Shell的基本功能
Deepin的Shell是Deepin操作系统中的一个重要组成部分,它为用户提供了一个与操作系统交互的界面。Shell是一种命令行解释器,用户可以通过它输入命令来执行各种操作,如文件管理、程序运行、系统配置等。
在Deepin操作系统中,Shell通常是Bash(Bourne-Again SHell)的一个版本,这是大多数Linux发行版中最常用的Shell。Bash具有强大的脚本语言能力,支持各种命令行操作,并且可以编写复杂的脚本程序。
用户可以通过Shell执行各种Linux命令,编写脚本自动化任务,以及进行系统管理和配置。Shell也是许多Linux发行版中默认的命令行解释器,因此,熟悉Shell对于Linux用户来说非常重要。在Deepin中,用户可以通过图形界面中的终端应用程序或通过系统的命令行界面来访问和使用Shell。
不同发行版本的Linux内置使用的默认shell是不一样的,有些是bash,有些是zsh,还有其他的,Ubuntu Linux就是使用的bash,kali Linux使用的是zsh。在后面使用父子shell的时候就可以体现出来。不同shell里面的语法大同小异。他们有区别,但不是没有关系。
1.1 进程列表
在使用shell命令的时候,在中间加上分号(;)即可实现同时操作多条命令,来提高效率,记得命令与命令之间要空格。进程列表是命令分组的一种。
例
1.2 优先级
1.3 Bash常用的快捷键
1.4 重定向
1.4.1 Bash的标准输入和输出
1.4.2 输出重定向
例
1.5 多命令执行符
1.5.1 分号;
语法
注意:
在不同的命令之间添加分号即可,当有错误的命令在里面的时候它可以不影响执行,命令之间没有逻辑关系
例
可以看见,以上命令全部执行了,错误的命令也会执行,跑代码就很方便了
1.5.2 逻辑符&&
语法
注意:
改用法和上面的分号的用法区别是双&&前一条命令要正确执行后面的命令才会执行,第一条命令错误执行时,第二条命令不会执行。
例
1.5.3 逻辑符||
语法
注意:
当第一个命令正确执行后,第二个就不会执行,当第一个命令执行不正确的时候,第二个命令就会执行。
例
1.6 Bash特殊符号
例
1.7 父子shell
什么是父shell,什么是子shell,看看下面这张图片,当我们使用pstree命令的时候,我我们可以看到这个命令是在shell的进程下面,这里为什么有两个bash,是因为我们在命令行界面运行了bash,他就要单独开了一个bash在父shell下面,所以前面的bash就是父shell,后面的bash就是子shell,当前进入子shell后,你的历史命令就会消失。
例
例
我们来看看上面的代码,我们在shell里面定义了一个变量name,值为zhong,当我们使用小括号执行的时候就变了,这是为什么,这里不是覆盖前面的值,而是在小括号里面的命令开了一个子shell,我们当前的shell就可以看作为父shell,所以,我们再次执行命令的时候看到的值还是zhong,如果是赋值被覆盖,那么最后一条命令就还是1;
当我们使用大括号的时候,他执行的命令就是在父shell里面执行的,而且必须注意的是,命令前后必须空格,否者就会像最后一行一样,语法是错误的。
查看当前是否使用了子shell还可以使用echo $BASH_SUBSHELL,注意不一定是BASH_SUBSHELL,要根据你当前使用的Linux默认的shell来命名,比如kali就是ZSH_SUBSHELL,如何查看当前使用的是bash还是其他的shell方式有很多,比如ps进程查看等。
注意:当echo $BASH_SUBSHELL的值是0的时候表示没有创建子shell来执行这些命令,如果输出的是1,表示创建了子shell来执行命令。
例
1.8 高效的子shell
1.8.1 后台模式
一种高效的子shell用法就是后台模式。演示后台模式的命令是sleep,睡眠的意思是吧,进程睡眠,该命令在shell脚本中常用于引入一段暂停时间。在命令的末尾加上&就会将命令至于后台模式。
例
注意:进入睡眠模式的时候的ID号和ps进程中睡眠模式的ID号是一样的。
将进程列表放置后台
例
1.8.2 协程
协程就是在后台生成一个子shell,二是在这个子shell里面执行命令。协程的处理需要用到oproc命令,将命令放置后台运行。
例
注意:协程是后台在运行,前台也可以进行交互,后台模式是进入了后台,无法再进行交互,除非退出来了或者再后面加上了&,加上&就会把命令放入后台,而不会进入后台里面
每次运行的时候,进程ID都是不一样的,但是还可以给进程起名字
例
当我们进程没有结束的时候开启新的进程的时候,旧的进程依然会运行,直到它结束
结合协程与进程列表
例
1.9 外部命令与内建命令
1.9.1 外部命令
外部命令也叫文件系统命令,是存在bash shell之外的程序,通常位于/bin、/usr/bin、/sbin或/usr/sbin目录中,例如ps就是外部的命令,使用which和type可以找到对应的文件名。
例
可以看见ps是外部的命令,而cd则是shell内建命令。
find没想到吧他也是外部命令,其实我也没想到。
当执行外部命令的时候就会创建一个子进程,这种操作叫做衍生。
例
所以你就知道为什么之前查看进程的时候每次都能看到ps,因为他是一个外部的命令,调用的时候会衍生子进程,在子进程里面执行外部命令,注意他们的PID号是不一样的。
当出现进程衍生的时候就会消耗时间和资源来设置新的子进程环境,所以外部命令的开销较高。
1.9.2 内建命令
内建命令与外部命令不同,它们不需要创建子进程来执行,他们和shell编译成了一体,作为shell的组成部分存在。
有些命令既有内建命令也有外部命令,例如pwd和echo。使用type -a即可看见他们所有的路径。
可以看见echo与pwd还有别的路径,他们不仅仅是shell内建命令。
注意:which只能看见外部命令
1.9.3 命令别名
查看当前系统可以使用的别名可以使用命令alias
例
设置别名
语法
例
注意:被定义的别名仅在当前的shell内有效,他是内建命令。
删除自己定义的别名
语法
例
变量(bash)
2.1 变量命名规侧
例
像这样可以变化的参数就是变量,他的值是不定的,可以进行覆盖变化。
2.2 变量的分类(按照存储类型)
2.3变量的分类
2.4 定义变量
语法
注意:等号之间不能空格,因为在操作系统中使用命令才用空格,如果你定义变量使用了空格,系统会认为是你使用了bash命令。
例
2.4.1 调用变量
语法
注意:Linux系统中,变量的值默认是字符串类型(String)。
例
2.4.2 变量叠加
语法
例
2.4.3 变量查看
直接使用set命令的时候就是查收看所有的变量
选项
在shell编程中,不存在的变量和变量值为空的时候调用出来都是空的,为了更好区分二者,使用set -u后不存在的变量就会报错,但是这是临时生效的,
例
2.4.4 变量删除
语法
2.5 环境变量
2.5.1 全局环境变量
全局变量对于shell会话和所有生成的子shell都是可见的。
查看全局变量可以使用命令env和printenv
例
可以看见二者几乎是一模一样。但是当要查看个别环境变量的时候就只能使用printenv。
例
可以看见查看个别环境变量的时候环境变量必须大写,env也是不能查看的。
查看当前的环境变量
语法
例
2.5.2 局部变量
局部变量只能在定义的进程中可见。
set、printenv、env命令之间的差距很细微,set命令既会显示全局和局部环境变量、用户自定义变量以及局部shell函数,还会按照字母顺序对结果进行排序。与set命令不同,env命令和printenv命令既不会对变量进行排序,也不会输出局部环境变量、局部用户自定义变量以及局部shell函数。在这种情况下,env命令和printenv命令的输出是重复的。不过,env命令有printenv命令不具备的一个功能,这使其略胜一筹。
2.5.3 设置环境变量
语法
2.5.4 环境变量与自定义变量的区别
环境变量和用户自定义变量最主要的区别在于,环境变量是全局变量,而用户自定义变量是局部变量。用户自定义变量只在当前的Shellr中生效,而环境变量会在当前Shel和这个Shell的所有子Shell当中生效
变量可以自定义,但是对系统生效的环境变量名和变量作用是固定的
当我们执行脚本的时候就需要指明脚本的路径,绝对路径或者是相对路径,如果向直接使用脚本命令就需要将该文将放入bin目录或者是将该文件目录添加到环境变量中去。
2.5.5 添加PATH变量的值
2.5.6 常用的环境变量
2.5.7 PS1环境变量
PS1变量是一种命令提示符设置,可以定义自己喜欢的提示符。
语法
注意:目录前面有空格,[ ]外有空格
选项
例
在Linux系统登录是主要生效的环境变量配置文件有以下五个
2.5.8 环境变量持久化
对全局环境变量(Linux系统的所有用户都要用到的变量)来说,可能更倾向于将新的或修改过的变量设置放在/etc/profile文件中,但这可不是什么好主意。如果升级了所用的发行版,则该文件也会随之更新,这样一来,所有定制过的变量设置可就都没有了。最好在/etc/profile.d目录中创建一个以.sh结尾的文件。把所有新的或修改过的全局环境变量设置都放在这个文件中。在大多数发行版中,保存个人用户永久性bash shell变量的最佳地点是HOME/.bashrc文件。这适用于所有类型的shell进程。但如果设置了BASH_ENV变量,请记住:除非值为HOME/.bashrc,否则,应该将非交互式shell的用户变量放在别的地方。
注意:图形化界面组成部分(比如GUI客户端)的环境变量可能需要在另外一些配置文件中设置,这和设置bash shell环境变量的文件不一样。
2.5.9 系统语序
locale 设置规则
<语言>_<地区>.<字符集编码><@修正值>
查询当前系统语系 locale
当前所有启动的locale
注意:
优先级:LC*ALL > LC_*> LANG****
查看当前系统语序
查看Linux支持的所有语系
查看默认语序
设置系统的 locale
2.6 位置参数变量
例
注意:
2.7 预定义变量
例
2.7.1 逻辑&&与||
2.7.2 接受键盘输入(input) read
语法
选项
例
注意
2.8 声明变量类型
使用declare声明变量类型
语法
选项
例
输出数组变量类型
通过下标来保存多个数据
例
2.9 数组变量
环境变量的一个很酷的特性是可以作为数组使用。数组是能够存储多个值的变量。这些值既可以单独引用,也可以作为整体引用
语法
例
语法
例
Shell运算符
例
3.1 运算符的优先级
3.2 运算方法
例1
例2
--逻辑或--
同为假才假,否则为真,同为0为0,否则为1,两个0才为0,其余为1
--逻辑与--
同为真才真,否则为假,同为1为1,否则为0,两个1才为1,其余为0
--按位与--
同为真才真,否则为假,同为1为1,否则为0,两个1才为1,其余为0
--按位或--
两个假才假,否则为真,同为0为0,否则为1,两个0才为0,其余为1
综上所述,逻辑与和按位与情况一样,反之
3.3 变量测试
变量的测试与内容置换,当我们不知道另外一个变量的时候,通过输出变量转换的式子,通过其中一个变量的值来进行另外一个变量的值的判断
变量测试多在Linux脚本优化的时候使用
例
可以通过以下示例来理解表的内容
配置文件
4.1 环境变量配置文件
环境变量配置文件中主要是定义对系统操作环境生效的系统默认环境变量,如PATH等。
登录的时候就会启用生效的环境变量由以下五个:
4.2 环境变量配置文件的功能
放在etc目录线面的会对所有用户生效,放在~家目录的只会对当前用户生效
登录Shell
** /etc/profile文件是系统中默认的bash shell的主启动文件。系统中的每个用户登录时都会执行这个启动文件。**
** etc/profile文件是bash shell默认的主启动文件。只要登录Linux系统,bash就会执行/etc/profile启动文件中的命令。**
/etc/profile的作用
umask权限
查看系统默认权限
基本访问权限
文件类型标识符
文件权限系统,将操作文件的用户分成三类:
注意
如何计算当前创建的目录的权限
用权限符号来进行计算,所有权限减去默认权限(umask的值022),取消掉相同的权限,留下的就是创建芯目录的权限
例
~/.bash_profile的作用
/etc/bashrc的作用
4.3 source
修改配置文件后使用该命令让文件直接生效,直接让脚本生效都可以,.在做命令使用的时候就是source
语法
其他配置文件
注销的时候生效的环境变量配置文件
~/.bash_logout
该文件默认是空的,只有当你执行关机的时候进行某种操作才会有内容
~/bash_history
该文件会保存你上次登录终端后使用的历史命令
若要修改历史命令的上限需要在.bashrc和/etc/profile文件中修改
Shell登录信息
本地终端欢迎信息:/etc/issue
远程终端欢迎信息:/etc/issue.net
shell正则表达式
5.1 正则表达式
正则表达式是用于描述字符排列和匹配模式的一种语法规则,它主要用于字符串的模式分割、匹配、查找及替换操作。
正则表达式与通配符
正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed等命令可以支持正则表达式。
通配符用来匹配符合条件的文件名,通配符是完全匹配。s、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。
通配符
最常用的是前三个
基础正则表达式
*示例
test.txt文本内容如下:
错误示例
注意:
原因是*本身就是字符匹配,匹配0个或任意个字符,所以会匹配所有的字符
.示例
注意:
".*"会匹配所有的内容
^与$示例
注意:
[]示例
注意:
当括号[]内外都有^的时候就表示否定的意思,除了括号里面的其他的都要,匹配的是开头行,括号要内的符号就表示取反,外面的符号就表示开头匹配
特别的例子
扩展正则表达式
例:匹配邮箱
[0-9a-zA-Z]+@[0-9a-zA-Z]+(.**[0-9a-zA-Z_]+){1,3}****
例:匹配IP
^(([0-9].)|(1-9.)|(1**0-9.)|(20-4.)|(25[0-5].)){3}(([0-9])|(1-9)|(10-9)|(20-4)|(25[0-5]))$**
5.2 字符截取
printf 格式化输出
语法
参数 输出格式:指定数据输出时的格式; 输出字符串:指定要输出的数据。 格式替代符
转义序列
例1
例2