目录
概念
逻辑卷标
- 关于档案与目录的侦测逻辑卷标!
-f 常用!侦测『档案』是否存在 eg: if [ -f filename ]
-d 常用!侦测『目录』是否存在
-b 侦测是否为一个『 block 档案』
-c 侦测是否为一个『 character 档案』
-S 侦测是否为一个『 socket 标签档案』
-L 侦测是否为一个『 symbolic link 的档案』
-e 侦测『某个东西』是否存在!
- 关于程序的逻辑卷标!
-G 侦测是否由 GID 所执行的程序所拥有
-O 侦测是否由 UID 所执行的程序所拥有
-p 侦测是否为程序间传送信息的 name pipe 或是 FIFO
- 关于档案的属性侦测!
-r 侦测是否为可读的属性
-w 侦测是否为可以写入的属性
-x 侦测是否为可执行的属性
-s 侦测是否为『非空白档案』
-u 侦测是否具有『 SUID 』的属性
-g 侦测是否具有『 SGID 』的属性
-k 侦测是否具有『 sticky bit 』的属性
- 两个档案之间的判断与比较 ;例如[ test file1 -nt file2 ]
-nt 第一个档案比第二个档案新
-ot 第一个档案比第二个档案旧
-ef 第一个档案与第二个档案为同一个档案( link 之类的档案)
- 逻辑的『和(and)』『或(or)』
&& 逻辑的 AND 的意思
|| 逻辑的 OR 的意思
运算符号
= 等于 应用于:整型或字符串比较 如果在[] 中,只能是字符串
!= 不等于 应用于:整型或字符串比较 如果在[] 中,只能是字符串
< 小于 应用于:整型比较 在[] 中,不能使用 表示字符串
> 大于 应用于:整型比较 在[] 中,不能使用 表示字符串
-eq 等于 应用于:整型比较
-ne 不等于 应用于:整型比较
-lt 小于 应用于:整型比较
-gt 大于 应用于:整型比较
-le 小于或等于 应用于:整型比较
-ge 大于或等于 应用于:整型比较
-a 双方都成立(and) 逻辑表达式 –a 逻辑表达式
-o 单方成立(or) 逻辑表达式 –o 逻辑表达式
-z 空字符串
-n 非空字符串
花括号
花括号
1. 名字扩展
test2()
{
echo {1..10}.txt
echo hello\ {a..f}
echo world{a..f}
}
test2
// 输出结果
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt 10.txt
hello a hello b hello c hello d hello e hello f
worlda worldb worldc worldd worlde worldf
2. 特殊替换
符号 | 含义 |
---|---|
${var} | 变量,界定范围 |
${var:-word} | 如果var为空或者未设定,返回word,var不变 |
${var:=word} | 如果var为空或者未设定,返回word,且var=word |
${var:+word} | 如果var有值,返回word,var不变 |
${var:?word} | 如果变量var为空或者未设定,返回word并退出shell,word没有值则输出:parameter null or not set,用于检测var是否被正常赋值 |
${var-word} | 如果var未设定,返回word,如果var未空或者有值,返回var |
${var:num} | 返回var中第num个字符到末尾的所有字符,正从左往右,负从右往左,有空格:${var: -2},没有空格:${var:1-3}或${var:(-2)} |
${var:num1:num2} | 从var的第num1个位置开始,提取长度为num2的子串。num1是位置,num2是长度 |
${var/word1/word2} | 将var中第一个匹配到的word1替换为word2 |
${var//word1/word2} | 将var中所有word1替换为word2 |
3. 模式匹配替换
{variable%pattern}
{variable%%pattern}
{variable#pattern}
{variable##pattern}
- 第一种模式:${variable%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最短的匹配模式
- 第二种模式: ${variable%%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
- 第三种模式:${variable#pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern开始,如果是,就从命令行把variable中的内容去掉左边最短的匹配模式
- 第四种模式: ${variable##pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
这四种模式中都不会改变variable的值,其中,只有在pattern中使用了*匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,*表示零个或多个任意字符,?表示仅与一个任意字符匹配,[…]表示匹配中括号里面的字符,[!…]表示不匹配中括号里面的字符。
示例(使用正则匹配)
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
重定向
将Linux 标准输出,错误输出重定向到文件
- 想要把make输出的全部信息,输出到某个文件中
make xxx > build_output.txt
此时默认情况是没有改变2=stderr的输出方式,还是屏幕,所以,如果有错误信息,还是可以在屏幕上看到的。 - 只需要把make输出中的错误(及警告)信息输出到文件中
make xxx 2> build_output.txt
相应地,由于1=stdout没有变,还是屏幕,所以,那些命令执行时候输出的正常信息,还是会输出到屏幕上,你还是可以在屏幕上看到的。 - 把make输出中的正常(非错误,非警告)的信息输出到文件中
make xxx 1> build_output.txt
相应地,由于2=stderr没有变,还是屏幕,所以,那些命令执行时候输出的错误信息,还是会输出到屏幕上,你还是可以在屏幕上看到的。 - 想要把正常输出信息和错误信息输出到分别的文件中
make xxx 1> build_output_normal.txt 2>build_output_error.txt
即联合使用了1和2,正常信息和错误信息,都输出到对应文件中了。 - 所有的信息都输出到同一个文件中
make xxx > build_output_all.txt 2>&1
其中的2>&1表示错误信息输出到&1中,而&1,指的是前面的那个文件:build_output_all.txt 。
运用
查看进程开启的线程数
// pstree -盘 进程号
pstree -p 175084 | wc -l
判断是否为数字
# 使用sed 正则方式
if [ -n "$(echo $1 | sed -n "/^[0-9]\+$/p")" ]; then
echo "$1 is number;"
else
echo "$1 no"
fi
n位自动补零
# 仅适用于数字
printf "%04d\n" 86
echo 86|awk '{printf("%04d\n",$0)}'
转换进制
报错: “value too great for base (error token is “00000001830”)”
原因: SHELL脚本中变量以“0”开头,则会被认为是八进制数字,而在八进制数字中出现8则为不合理,遂报该错误。
# 先将变量转换为十进制,然后再做运算即可,
# 修改后的该行代码为
bill_id2=`echo $(( 10#00482 + 2 ))`
除法运算
bc在计算时, 如果结果小于1, 那么前面将会少个0. 可以用awk方式来进行运算
echo 5 3 | awk '{ printf "%d\n" ,$1/$2}'
echo 5 3 | awk '{ printf "%d\n" ,$1/$2+0.5}'
echo 4 3 | awk '{ printf "%d\n" ,$1/$2+0.5}'
打印个进度条
#!/bin/bash
b=''
i=0
while [ $i -le 100 ]
do
printf "[%-50s] %d%% \r" "$b" "$i";
sleep 0.2
((i=i+2))
b+='#'
done
echo
逐行读取字符串或文件
s="hekll\nfjdks\nd123"
echo -e "${s}" | while read line
do
echo "line: ${line}"
done
但是这样写的话,while循环里面的变量不能作用到while之外(因为使用了管道,while循环相当于是一个子shell)
改成这样即可
s="hekll\nfjdks\nd123"
while read line
do
echo "line: ${line}"
done <<< "${s}"
读取文件
while read line
do
echo "line: ${line}"
done < ${filename}
判断命令是否存在
用几种方法以判断 vim
命令是否存在
command命令
if command -v vim >/dev/null 2>&1; then
echo "exists vim"
fi
type命令
if type vim >/dev/null 2>&1; then
echo "exists vim"
fi
hash命令
if hash vim 2>/dev/null; then
echo "exists vim"
fi
知识点
EOF使用注意
EOF内部在使用内部变量和外部变量时需要特别注意,使用不当则会遇到不可预期的结果。
EOF块中的部分就是被转换成了新的字符串被重定向到新的shell命令作为输入,在重定向之前,里面的所有外部变量都会被替换成具体的值
- 配对的结尾EOF需要顶格写
- 使用内部变量需要加上转义字符,不然就会被认为是使用的外部变量。如果外部没有定义,则为空
s="hello world"
bash << EOF
# 使用的外部变量,不需要转义
echo "s: ${s}"
code=20
# 使用的内部变量,需要使用转义
echo "code: \${code}"
echo "\$?"
exit 10
EOF
echo "$?"
set
set -u
在执行未定义的变量时报错
等价于 set -o nounset
在没有 set -u
的情况下,下面的shell是可以正常执行的,输出为空,在增加了 set -u
后,在执行该shell会提示错误。
echo ${hello}
set -x
输出shell代码
等价于 set -o xtrace
下面的代码不仅会输出 “hello world” 还会在输出结果之前输出执行的代码 echo 'hello world'
set -x
echo "hello world"
set -e
当发生错误时,终止程序执行。
上面的命令在把 -
改为 +
时,效果与之相反。
路径title
if [[ "${0:0:1}" == "/" ]]; then
SCRIPT=${0}
else
SCRIPT=`pwd`/${0}
fi
ROOTDIR=`dirname ${SCRIPT}`
echo ${SCRIPT}
echo ${ROOTDIR}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 245292011@qq.com