常用bash命令
ls -l
:<<EOF
# 以下分别是文件夹和文件的结果
drwxr-xr-x@ 31 eric staff 992 4 18 2024 code-pre
-rwxr-xr-x@ 1 eric staff 933 12 27 01:13 test.sh
第一个字符:表示文件类型:
d(表示目录/文件夹)【常见】
-(表示文件)【常见】
b(块文件,比如磁盘,光驱,软盘)【不常见,了解】
c(字符文件,比如系统设备文件:/dev/null)【不常见,了解】
p(管道文件)【不常见,了解】
接下来的每三个一组分别是Owner(所有者)、Group(所属组)、others(其他用户)的权限
r(4):代表读(read)权限
w(2):代表写(write)权限
x(1):代表执行(execute)权限
接下来的数字:代表硬连接数,即有多少个硬链接指向这个文件或目录
普通文件一般是1,目录至少是2,因为除自身(.)还有上级目录(..)也是指向该目录的硬链接
eric:是文件或目录的所有者
staff:所属组
接下来的数字是文件或目录大小(字节数)
接下来是月,日,时分
EOF
chmod +x file
chmod 1 file
chmod 755 file
chmod +rwx file
chmod -r file
chmod -rwx file
chmod =r file
chmod =w file
chmod =rw file
chmod =x file
chmod u+x file
chmod g+x file
chmod o+x file
history
echo $HISTFILE
history -c
!-n
!!
!$
history n
alias h5='head -5'
unalias h5
cat ./filePath | head -n
:<<EOF
~/.bash_profile
~/.zshrc
EOF
:<<EOF
/dev/null:空设备文件,类似无限大的垃圾回收站(丢进去的东西无法恢复)
0:标准输入,路径:/dev/stdin
1:标准输出,路径:/dev/stdout
2:标准错误,路径:/dev/stderr
>:标准输出重定向,与1>相同
2>&1:把标准错误输出 重定向到 标准输出
&>file:标准输出 和 标准错误输出 都重定向到文件file中
>&file:标准输出 和 标准错误输出 都重定向到文件file中
EOF
command 1> file
command > file
command 2> file
command &> file
command &> /dev/null
command >> file
command 2>> file
command $>> file
command < file
cat exam.sh
while read str
do
echo $str
done < exam.sh
command file
:<<EOF
-c:统计字节数
-w:统计单词数
-l:统计行数
EOF
wc -l < exam.sh
wc -l << END
:<<EOF
运行结果:
**Desktop** wc -l << END
heredoc> 1
heredoc> 2
heredoc> 3
heredoc> END
3
**Desktop**
EOF
man ls | less
cat /etc/password | tee exam.sh
cat /etc/password | tee -a exam.sh
command1 && command2
ls / && echo "success"
ls dir && echo "success"
command1 || command2
ls / || echo "success"
ls dir || echo "success"
cd /usr/local; echo "ignore"
通配符(和正则有一点不同)
| 字符 | 含义 | 实例 |
|---|
| * | 匹配0个或多个任意字符 | a*b,a与b之间可以有任意长度的字符,也可以没有。例如:aabcb, ab, azxcb... |
| ? | 匹配一个任意字符 | a2b,a与b之间必须但也只能存在一个字符,该字符可以是任意字符。例如:aab, abb, acb... |
| [list] | 匹配Iist中的任意单个字符 | a[xyz]b,a与b之间必须但也只能存在一个字符,该字符只能是x或y或2。例如:axb,ayb,azb |
| [!list] | 匹配除list中的任意单个字符 | a[!a-z]b,a与b之间必须但也只能存在一个字符,该字符不能是小写字母。例如:aAb,a0b... |
| [c1-c2] | 匹配c1-c2间的任意单个字符 | a[0-1]b,a与b之间必须但也只能存在个字符,该字符只能是数字。例如:a0b,a1b... |
| {string1,string2,...} | 匹配string1、string2等中的一个字符串 | a{abc,xyz,opq}b,a与b之间必须但也只能存在一个字符串,字符串只能是abc或xyz,opq,...。例如:aabcb, axyzb,aopqb,... |
八、Shell脚本规范
cat /etc/shells
:<<EOF
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
EOF
echo $SHELL
:<<EOF
• 直接使用./a.sh来执行这个脚本的时候,如果没有shebang,就会默认使用$SHELL指定的解释器,否则就会用shebang指定的解释器
• 上面这种写法可能不太具备适应性,一般我们会用下面的方式来指定:#!/bin/bash/env bash1,这里不太懂先跳过
EOF
:<<EOF
注释的意义不仅在于解释用途,而在于告诉我们注意事项,就像是一个 README。
具体的来说,对于Shell脚本,注释一般包括不面几个部分:
• shebang
• 脚本的参数
• 脚本的用途
• 脚本的注意事项
• 脚本的写作时间,作者,版权等
• 各个函数前的说明注释
• 一些校复杂的单行命令注释
EOF
:<<EOF
• 这一点很重要,当脚本需要接受参数的时候,一定要先判断参数是否合乎规范,并给出合适的回显,方便使用者了解参数的使用。
• 最少,最少,最少得判断下参数的个数
EOF
if [[ $# != 2 ]]; then
echo "parameter incorrect"
exit 1
fi
:<<EOF
• 一般情况下会将一些重要的环境变量定义在开头,确保这些变量的存在。
• 这种定义方式有一个很常见的用途,最典型的应用就是,当本地安装了很多 java 版本时,可能需要指定一个java来用,这时就会在脚本开头重瓶定义JAVA_HOME以及PATH变量来进行控制。
• 一段好的代码通常是不会有很多硬编码在代码里的“魔数"的。如一定要有,通常是用一个变量的形式定义在开头,然后调用的时候直接调用这个变量,这样方便日后的修改。
EOF
source ~/.bash_profile
source $ZSH/oh-my-zsh.sh
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
:<<EOF
• 因为很多需要缩进的地方(比如if,for语包)都不长,很多人都懒得去缩进,而旦很多人不习惯用函数,导致缩进功能披弱化。
• 正确的缩进是很重要的,尤其是在写函数的时候,否则在阅读的时候很容易把函数体跟直接执行的命令搞混。
• 常见的缩进方法主要有"soft tab”和"hard tab'两种:
• 所谓soft tab就是使用n个空格进行缩进(n通常是2或4)
• 所谓hard tab当然就是指真实的"\t"字符
• 对于if和for语句之类的,最好不要把then,do这些关键字单独写一行,这样看上去比较丑。
EOF
:<<EOF
所谓命名规范,基本包含下面这几点:
• 文件名规范,以.sh结尾,方便识别
• 变量名字要有含义,不要拼错
• 统一命名风格,写Shell一般用小写字母加下划线
EOF
:<<EOF
在写脚本的时候尽量使用UTF-8编码,能够支持中文等一些奇奇怪怪的字符。不过虽然能写中文,但是在写注释以及打log的时候还是尽量英文,毕竟很多机器还是没有直接支持中文的,打出来可能会有乱码。
EOF
:<<EOF
• 日志的要性不必多说,能够方便回头纠错,在大型的项目里是非常重要的。
• 如果这个脚本是供用户直接在命令行使用的,那么最好还要能够在执行时实时回显执行过程,方便用户掌
控。
• 为了提高用户体验,会在回显中添加一些特效,比如颜色啊,闪烁啊之类的。
EOF
:<<EOF
• 不要把密码硬编写在脚本,尤其是当脚本托管在Github这类平台中时。
EOF
:<<EOF
• 在调用某些程序的时候,参数可能会很长,这时候为了保证较好的阅读体验,我们可以用反斜杠来分行,注意:放斜杠前有个空格
EOF
echo "a \
b \
c \
"
:<<EOF
• 在使用命令的时候要了解命令的具体做法,尤其当数据处理量大的时候,要时刻考虑该命令是否会影响效率
• 比如下面的两个sed命令:
sed -n '1p' file
sed -n '1p;1q' file
作用一样,都是获取文件的第一行.但是第一条命令会读取整个文件,而第二条命令只读取第一行。当文件很大的时候,仅仅是这样一条命令不一样就会造成巨大的效率差异。
当然,这里只是为了举一个例子,这个例子真正正确的用法应该是使用head-n file命令
勤用双引号
• 几乎所有的大佬都推荐在使用"$"来获取变量的时候最好加上双引。
• 不加上双引号在很多情况下都会造成很大的麻烦
EOF
:<<EOF
• 很多情况下,会先获取当前脚本的路径,然后以这个路径为基准,去找其他的路径。通常我们是直接用pwd以获得脚本的路径。
• 不过其实这样是不严谨的,pwd 获得的是当前Shell的执行路径,而不是当前脚本的执行路径。
• 正确的做法应该是下面这两种:
script_dir=$(cd $(dirname $0) && pwd)
script_dir=$(dirname $(readlink -f $0 ))
• 应当先cd进当前脚本的目录然后再pwd,或者直接读取当前脚本的所在路径。
EOF
:<<EOF
• 这里的简短不单单是指代码长度,而是指用到的命令数。原则上我们应当做到,能一条命令解决的问题绝不用两条命令解决。这不仅牵涉到代码的可读性,而且也关乎代码的执行效率。
• 最最经典的例子如下:
cat /etc/passwd grep root
grep root /etc/passwd
• cat命令最为人不齿的用法就是这样,用的没有任何意义,明明一条命令可以解決,非得加根管道
EOF
:<<EOF
这里的新写法不是指有多厉害,而是指可能更希望使用较新引入的一些语法,更多是偏向代码风格的.
• 尽量使用func(){}来定义函数,而不是func(){}
• 尽量使用[[]]来代替[]
• 尽量使用$()将命令的结果赋给变量,而不是反引号在复杂的场景下尽量使用# #printf代替echo进行回显
EOF
:<<EOF
• 路径尽量保持绝对路径,不容易出错,如果非要用相对路径,最好用./修饰
• 优先使用bash的变量替换awk sed,这样更加简短
• 简单的if尽量使用 && ||,写成单行,比如:[[ $x > 2 ]] && echo $x
• 当export变量时,尽量加上子脚本的namespace,保证变量不冲中突【就是多加一下前缀】
• 会使用trap捕获信号,并在接受到终止信号时执行一些收尾工作
• 使用mktemp生成临时文件或文件夹
• 利用/dev/null过滤不友好的输出信息
• 会利用命令的返回值判断命令的执行情况
• 使用文件前要判断文件是否存在,否则做好异常处理
• 不要处理ls后的数据,比如:ls -l | awk '{print $8}'
• ls结果非常不确定,并且与平台有关
• 读取文件吋不要使用fot loop而要使用while read
EOF
shell脚本调试
sh [-nv] file.sh
:<<EOF
• -n:不要执行script,仅查询语法的问题
• -v:在执行script之前,先将script的内容输出到屏幕上
• -x:将使用的脚本的内容输出到屏幕吧,改参数经常被使用
EOF
sh -n file.sh
sh -v file.sh
sh -x file.sh
set -xve
脚本运行
./file.sh
sh file.sh
bash file.sh
`pwd`/file.sh
. file.sh
source file.sh
作业脱机管理
:<<EOF
1、将作业(进程)切换到后台可以避免由于误操作如:ctrl+c等导致的job被异常中断的情形,而脱机管理主要是针对终端异常断开的情形。
2、通常使用nohup命令来使得脱机或注销之后,Job依旧可以继续运行。也就是说nohup忽略所有挂断(SIGHUP)信号。
3、如果该方式命令之后未指定&符号,则job位于前台,指定&符号,则job位于后台。
EOF
nohup exam.sh
ps -ef | grep ./exam.sh
more nohup.out
nohup exam.sh &> temp2.log &
jobs
screen命令使用
:<<EOF
一、简介
Screen 是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。
1、会活恢复
• 只要Screen本易没有终止,在其内部运行的会话部可以恢复。这一点对于远程登录的用户特别有用,即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen-r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。这一点和图形界面下的VNC很相似。
2、多窗口
• 在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等:还提供了类似滚动条的功能,可以直看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。会话共享Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保
3、安装screen
yum install screen
rpm -qa | grep screen # 查看安装好的命令
4、语法
screen [AmRvx -ls wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s][-S <作业名称>]
-A 将所有的视窗都调整为目前终端机的大小。
-d <作业名称> 将指定的screen作业离线。
-h <行数> 指定视窗的缓冲区行数。
-m 即使目前已在作业中的screen作业,仍强制建立新的scneen作业。
-r <作业名称>恢复窗线的screen作E业。
-R 先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s 指定建立新视窗时,所要执行的Shel1。
-S <作业名称> 指定screen作业的名称。
-v 显示版本信息。
-x 恢复之前离线的screen作业。
-ls或--list 显示目前所有的screen作业。
-wipe 检查目前所有的screen作业,并删除已经无法使用的screen作业。
EOF
screen -S yourname
screen -ls
screen -r yourname
screen -d yourname
screen -d-r yourname
screen -dms session_name
screen -X -S [session
screen -ls
screen -r session_name
screen -wipe