shell记不住

目录


概念

逻辑卷标

  1. 关于档案与目录的侦测逻辑卷标!
-f    常用!侦测『档案』是否存在 eg: if [ -f filename ]
-d    常用!侦测『目录』是否存在
-b    侦测是否为一个『 block 档案』
-c    侦测是否为一个『 character 档案』
-S    侦测是否为一个『 socket 标签档案』
-L    侦测是否为一个『 symbolic link 的档案』
-e    侦测『某个东西』是否存在!
  1. 关于程序的逻辑卷标!
-G    侦测是否由 GID 所执行的程序所拥有
-O    侦测是否由 UID 所执行的程序所拥有
-p    侦测是否为程序间传送信息的 name pipe 或是 FIFO
  1. 关于档案的属性侦测!
-r    侦测是否为可读的属性
-w    侦测是否为可以写入的属性
-x    侦测是否为可执行的属性
-s    侦测是否为『非空白档案』
-u    侦测是否具有『 SUID 』的属性
-g    侦测是否具有『 SGID 』的属性
-k    侦测是否具有『 sticky bit 』的属性
  1. 两个档案之间的判断与比较 ;例如[ test file1 -nt file2 ]
-nt    第一个档案比第二个档案新
-ot    第一个档案比第二个档案旧
-ef    第一个档案与第二个档案为同一个档案( link 之类的档案)
  1. 逻辑的『和(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

文章标题:shell记不住

字数:2.5k

本文作者:常丁方

发布时间:2020-07-12, 09:48:21

最后更新:2021-08-25, 18:31:45

原始链接:http://changdingfang.com/2020/07/12/notes/linux/shell-forget/
×

喜欢就点赞,疼爱就打赏

资源