注:前言、目录见 https://blog.csdn.net/qq_44220418/article/details/108428971

Tips:其实主要也就是把菜鸟教程上的shell编程教程过了一遍,自己探索了一部分,记录了自己的所得与理解

文章目录

  • 一、注释
  • 二、输出
    • 1、`echo`命令
    • 2、`printf`命令
  • 三、变量
    • 1、定义
    • 2、使用
    • 3、删除
  • 四、字符串
    • 1、表示
    • 2、拼接
    • 3、长度
    • 4、截子串
    • 5、查位置
  • 五、数组
    • 1、定义
    • 2、取元素
    • 3、长度
  • 六、运行与传参
    • 1、运行
    • 2、运行传参
  • 七、运算符
    • 1、算术运算符
    • 2、关系运算符
      • (1).条件表达式
      • (2).关系运算符
    • 3、逻辑运算符
    • 4、字符串运算符
    • 5、文档测试运算符
    • 6、`test`命令
      • (1).数值测试
      • (2).字符串测试
      • (3).文件测试
      • (4).组合逻辑运算符
  • 八、流程控制语句
    • 1、条件判断语句
      • (1).`if`语句
      • (2).`case`语句
    • 2、循环语句
      • (1).`for`循环
      • (2).`while`循环
      • (3).`until`循环
      • (4).跳出循环
  • 九、函数
  • 十、输入/输出重定向
  • 十一、文件包含

一、注释

#单行注释:<<EOF
多行注释
多行注释
多行注释
EOF

二、输出

1、echo命令

可以使用echo命令输出相关内容(字符串,可以是双引号字符串、单引号字符串、命令的执行结果……)

str="hello"echo 'hello world'       # hello world
echo "${str} world"       # hello world
echo "\"${str} world\"" # "hello world"
echo `ls | wc -l`     # 1

像是\"这样的转义,echo命令可以直接识别

如果要识别\n\c这样的特殊字符,需要为echo命令加上参数-e

echo -e "123\ntest"

也可以配合重定向符>>>将输出内容输出到文件

echo -e "1\n2\n3\n45" > 1.txt

2、printf命令

printf命令模仿 C 程序库里的printf()函数

一般格式如下:

printf "格式控制字符串" [参数列表]

和C语言一样,printf命令支持如下格式替代符

格式替代符 说明 示例结果
%d int
%ld long
%lld long long
%o 八进制整数
%x 十六进制整数(小写) 7f
%X 十六进制整数 (大写) 7F
%#x 十六进制整数(带前缀小写) 0x7f
%#X 十六进制整数(带前缀大写) 0X7F
%f float
%lf double
%e 指数形式浮点数 1.565600e+02
%c char
%s 字符串

注:
\qquad格式替代符都以%打头,要对%进行转义的话,应使用%%而不是\%

还有以下一些特殊的控制

格式字符串 说明 示例
%.mf m是一个整数,表示输出实数时小数点后保留m %.5f
%-md m是一个整数,表示输出整数时至少占m个字符的位置,并左对齐,类似的也可以用%-ms%-mf %-5d
%md m是一个整数,表示输出整数时至少占m个字符的位置,并右对齐,类似的也可以用%ms%mf %5d

这些特殊控制是可以组合使用的,如:%-8.6f代表输出一个至少占8个字符后左对齐的、保留到小数点后6位的实数

下面是常用的特殊字符

特殊字符 说明 示例
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效)
而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd d代表一个0∼70 \sim 70∼7的数字(或者缺省) '\65'就相当于ASCII编码为53的字符'5'
\0ddd d代表一个0∼70 \sim 70∼7的数字(或者缺省) '\0065'就相当于ASCII编码为53的字符'5'
\xddd d代表一个0∼f0 \sim \text{f}\;0∼f的数字(或者缺省) '\x56'就相当于ASCII编码为86的字符'V'
# 引号的区别
printf "%d\n" 566 # 556
printf '%d\n' 556 # 556
printf %d\n 556     # 556n(不换行)# 格式控制
printf "|%8.2f|%-6d|%-5s|\n" 3.141 123 ab # |    3.14|123   |ab   |# 缺省值
printf "%d %d %d\n" 12 3  # 12 3 0# 多余参数
printf "%d %d " 123 456 789   # 123 456 789 0 (不换行)

注:
\qquad① 单引号、双引号没有区别;不加引号时格式替代符可以正常输出,但是像\n这样的转义字符无法正常输出
\qquad② 缺少的参数
\qquad\qquad%c%s用空字符、空串填充
\qquad\qquad%d%ld%lld0填充
\qquad\qquad%f%lf0.000000填充
\qquad\qquad%e0.000000e+00填充
\qquad③ 多余的参数会重复使用前面的格式字符串继续进行输出(多余不足时用缺省填充)

三、变量

1、定义

定义变量时,类似Python,可以直接通过赋值来定义变量,不需要加$符号

变量名的命名须遵循如下规则:

  • 命名只能使用英文字母、数字、下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线(_)
  • 不能使用标点符号
  • 不能使用bash里的关键字(可用help命令查看保留关键字)

2、使用

使用变量时,通过$符号来进行使用,形如$a${a}

在执行时,系统会将其替换为其相应的值,因此定义变量后再次赋值仍不需要用$符,像定义时一样赋值即可,可以理解为重定义

a=2
${a}=3 # (错误的重新赋值) 报错:2=3: command not found...
a=3        # (正确的重新赋值)

通过在变量名前加上前缀readonly可以将变量定义为只读变量

readonly a=2b=3
readonly b

3、删除

使用unset删除某个变量

a=2
unset a

四、字符串

1、表示

单引号字符串

\qquad单引号字符串的限制:
\qquad\qquad单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
\qquad\qquad单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用

双引号字符串

\qquad双引号字符串的优点:
\qquad\qquad双引号里可以有变量
\qquad\qquad双引号里可以出现转义字符

2、拼接

可以直接将一个字符串写在另一个字符串的后面完成拼接

echo '12341''12421414'  # 1234112421414
echo "12341""12421414"  # 1234112421414a=2
echo "a"$a"a"  # a2a

3、长度

通过#获取字符串长度

str="adc"
echo ${#str}  # 3

4、截子串

通过:n截取子串(从下标为n的字符开始截取到最后)
通过:n:m截取子串(从下标为n的字符开始往后截取m个字符)

str="0123456789"echo ${str:2:4}  # 2345
echo ${str:2}  # 23456789

5、查位置

通过expr index "$str" 要查找的字符们来查找这些字符在字符串str中第一次出现的位置(是从1开始的编号,而不是从0开始的索引)

str="abcd1234"echo `expr index "${str}" a`    # 1
echo `expr index "${str}" 1`    # 5
echo `expr index "${str}" c1`   # 3

五、数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小

1、定义

用括号声明数组

# 形式1
数组名=(值1 值2 ... 值n)# 形式2
数组名=(
值1
值2
...
值n
)

也可以通过定义数组的分量来定义数组(下标可以不连续,下标范围无限制)

数组名[下标1]=值1
数组名[下标2]=值2
数组名[下标n]=值n

2、取元素

在数组中取单个元素的格式如下

# 获取数组中指定下标的元素
${数组名[下标]}# 获取数组中首元素
${数组名}

注:直接访问数组名并不是获得全部元素,而是获得数组下标为0的元素


在数组中取全部元素的格式如下

${数组名[@]}${数组名[*]}

Tips:用@和用*只有在被双引号引用时才有区别,可以参考博客 https://blog.csdn.net/asty9000/article/details/86681517


示例

arr=(1 23 456 7890)echo ${arr}      # 1
echo ${arr[2]}  # 456
echo ${arr[@]} # 1 23 456 7890)

3、长度

使用#取长度(可以取数组的长度,也可以取元素的长度)

arr=(1 23 456 78)echo ${#arr}   # 1
echo ${#arr[0]} # 1
echo ${#arr[2]} # 3echo ${#arr[@]} # 4

六、运行与传参

1、运行

编写完sh脚本后,使用chmod命令为其添加可执行权限,然后指定sh脚本的位置,运行

chmod a+x test.sh
./test

2、运行传参

运行sh脚本前,是可以传入参数的

./test 1 2 34 5678

以上述传入的参数为例,解释一下处理参数的特殊字符

参数处理 说明 在上述示例中
$n 传入脚本的第n个参数 比如$1$2就对应了传入脚本的第1个参数(1)、第2个参数(2)
$# 传入脚本的参数个数 4
$* 传入脚本传递的所有参数(以单字符串方式)
"$*"相当于"$1 $2 ... $n"(一个元素)
1 2 34 5678
$@ 传入脚本传递的所有参数(以多字符串方式)
"$@"相当于"$1" "$2" ... "$n"(一堆元素)
1 2 34 5678
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态{0没有错误其他有错误\begin{cases}0 & 没有错误\\ 其他 & 有错误\end{cases}{0其他​没有错误有错误​

七、运算符

1、算术运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awkexprexpr最常用

expr是一款表达式计算工具,使用它能完成表达式的求值操作

a=21
b=5echo `expr ${a} + ${b}`      # 26
echo `expr ${a} - ${b}`       # 16
echo `expr ${a} \* ${b}`  # 105
echo `expr ${a} / ${b}`       # 4
echo `expr ${a} % ${b}`       # 1echo $((a + b))             # 26
echo $((a - b))             # 16
echo $((a * b))             # 105
echo $((a / b))             # 4
echo $((a % b))             # 1

Tips:使用以下形式快速计算表达式,并且不需要使用$符对变量进行使用
\qquad可以使用$((表达式))直接使用+-++--等进行算术运算(有时候加上$后,执行表达式后会提示命令不存在)
\qquad可以使用$[表达式]直接使用+-++--等进行算术运算
\qquad可以使用let 表达式直接使用+-++--等进行算术运算

其中
\qquad$((表达式))$[表达式]$会把运算返回的结果当成命令,有时候会提示命令XXX不存在
\qquad不加$的话,((表达式))可以无误执行,但[表达式]不行
\qquad只是对变量进行操作的话,建议使用let 表达式的写法

一些特殊的表达式用法,推荐这篇博客 https://blog.csdn.net/x1269778817/article/details/46535729

2、关系运算符

(1).条件表达式

这些概念是我的理解,用词等不一定很官方、很专业

条件表达式返回逻辑真true / 逻辑假false

条件语句是条件表达式的一部分,可以说,给条件语句加上适当的格式就成了条件表达式
eg:eg:eg:$a -ge 100是条件语句,[ $a -ge 100 ]是条件表达式

像是[ 条件语句 ]这样的格式为条件表达式(注意[]两边必须有空格

条件表达式似乎有很多种,可以是[ 条件语句 ][[ 条件语句 ]](( 条件语句 ))test 条件语句,用的比较多的就是[ 条件语句 ]

至于它们有什么区别,下面 [[ ]] 和 [ ] 的区别 会讲到

(2).关系运算符

关系运算符,大多-开头,我理解为整数关系运算符,如大于-gt、小于等于-le……
这些只能用作整数(或整数字符串)间比较

运算符 说明 使用示例
-eq 相等 [ $a -eq $b ]
-ne 不等 [ $a -ne $b ]
-gt 大于 [ $a -gt $b ]
-lt 小于 [ $a -lt $b ]
-ge 大于等于 [ $a -ge $b ]
-le 小于等于 [ $a -le $b ]

还有两个运算符==!=,我也将它们归到关系运算符中,它们可以比较的东西很多

运算符 说明 使用示例
== 相等 [ $a == $b ]
!= 不等 [ $a != $b ]

整数间关系示例

a=15
b=20# 相等
if [ ${a} -eq ${b} ]
thenecho "a==b"
fi# 不等【true】
if [ ${a} -ne ${b} ]
thenecho "a!=b"
fi# 大于
if [ ${a} -gt ${b} ]
thenecho "a>b"
fi# 小于【true】
if [ ${a} -lt ${b} ]
thenecho "a<b"
fi# 大于等于
if [ ${a} -ge ${b} ]
thenecho "a>=b"
fi# 小于等于【true】
if [ ${a} -le ${b} ]
thenecho "a<=b"
fi

不同类型判等示例

a=(5 6)
b="5 6"# 语法错误1 —— [: 参数太多
if [ ${a} != ${b} ]
thenecho "yes"
fi# 无语法错误【"5" != "5 6":true】
if [ "${a}" != "${b}" ]
thenecho "yes"
fi# 语法错误2 —— [: 参数太多
if [ "${a[@]}" != "${b}" ]
thenecho "yes"
fi# 无语法错误【"5 6" != "5 6":false】
if [ "${a[*]}" != "${b}" ]
thenecho "yes"
fi##################################c=56
d="56a"# 【"56" != "56a":true】
if [ "${c}" != "${d}" ]
thenecho "yes"
fi

Tips:
\qquad建议在使用==!=跨类别判等时,为使用的变量加上双引号"、使用整个数组时用双引号"*

\qquad有时候==[[ ]]的一些特殊用法结合起来用时,可能会出现问题,要注意点
\qquad比如[[ ${c}+${d} == 49 ]][[ ${c}+${d}==49 ]]的返回情况居然不一样,逻辑上判断应该是后者正确,也没搞明白为什么会这样(可能是运算符的优先级变了?)

3、逻辑运算符

逻辑运算,也就是与、或、非

逻辑非的写法只有一种,那就是[ ! 条件语句 ]

逻辑与的写法有两种
\qquad一种是[ 条件语句1 -a 条件语句2 ]
\qquad一种是[[ 条件语句1 && 条件语句2 ]]

逻辑或的写法有两种
\qquad一种是[ 条件语句1 -o 条件语句2 ]
\qquad一种是[[ 条件语句1 || 条件语句2 ]]

运算符 说明 使用示例
! 逻辑非 [ ! $a -ge 0 ]
-a 逻辑与 [ $a -ge 0 -a $b -ge 0 ]
-o 逻辑或 [ $a -ge 0 -o $b -ge 0 ]
&& 逻辑与 [[ $a -ge 0 && $b -ge 0 ]]
|| 逻辑或 [[ $a -ge 0 || $b -ge 0 ]]

使用示例

c=4
d=45# 【true】
if [ ${c} == 4 -a ${d} == 45 ]
thenecho "yes1"
fi# 【true】
if [[ ${c} == 4 && ${d} == 45 ]]
thenecho "yes2"
fi# 【false】
if [ ${c} != 4 -o ${d} != 45 ]
thenecho "yes3"
fi# 【false】
if [[ ${c} != 4 || ${d} != 45 ]]
thenecho "yes4"
fi# 【true】
if [[ ! ${c} != 4 ]]
thenecho "yes5"
fi

[[ ]]的条件表达式与[ ]的条件表达式不同(关于这一点,可见博客 shell逻辑判断&&和-a区别)

\qquad[[ ]]中可以使用><直接判断大于小于,也可以使用-gt-le等运算符
\qquad[ ]中只能使用-gt-le等运算符,><会被误解成重定向符号

\qquad[[ ]]中只能使用&&||进行逻辑与、逻辑或
\qquad[ ]中只能使用-a-o进行逻辑与、逻辑或

\qquad[[ ]]中可以直接使用+-等算术运算符(进行了算术扩展)
\qquad[ ]中不能直接使用+-等算术运算符

\qquad[[ ]]中可以直接使用正则表达式
\qquad[ ]中无法直接使用正则表达式

使用示例

c=4
d=45# 可以直接使用<,必须使用&&【true】
if [[ ${c} < ${d} && ${d} -gt ${c} ]]
thenecho "yes1"
fi# 可以直接使用+【true】
if [[ ${c}+${d} -eq "49" ]]
thenecho "yes2"
fi# 可以直接使用正则表达式(不要加上引号)【true】
if [[ ${d} == *5 ]]
thenecho "yes3"
fi

4、字符串运算符

字符串相关运算符如下表所示:

运算符 说明 使用示例
= 相等 [ $a = $b ]
!= 不等 [ $a != $b ]
-z 长度为0 [ -z "$a" ]
-n 长度非0 [ -n "$a" ]
非空 [ $a ]

使用示例

a="  "
b="123a"
c="123a"# 【true】
if [ "${b}" = "${c}" ]
thenecho "yes1"
fi# 【true】
if [ "${a}" != "${c}" ]
thenecho "yes2"
fi# 【false】
if [ -z "${a}" ]
thenecho "yes3"
fi# 【true】
if [ -n "${a}" ]
thenecho "yes4"
fi# 【true】
if [ "${a}" ]
thenecho "yes5"
fi

Tips:
\qquad多加引号,比如${a}有时候最好写成"${a}",否则空格串很有可能被处理成空串

5、文档测试运算符

文件测试运算符用于检测Linux的文件的各种属性

运算符(大致使用格式) 说明
-b file 检测file是否是块设备文件
-c file 检测file是否是字符设备文件
-d file 检测file是否是目录
-f file 检测file是否是普通文件
-S file 检测file是否为Socket
-L file 检测file是否为符号链接
-g file 检测file是否设置了SGID位
-k file 检测file是否设置了粘着位(Sticky Bit)
-u file 检测file是否设置了SUID位
-p file 检测file是否有名管道
-r file 检测file是否可读
-w file 检测file是否可写
-x file 检测file是否可执行
-s file 检测file是否非空
-e file 检测file是否存在

使用示例

# 【全部为true】if [ -f test.sh ]
thenecho "文件存在"
fiif [ -s test.sh ]
thenecho "文件非空"
fiif [ -w test.sh ]
thenecho "文件可写"
fiif [ -x test.sh ]
thenecho "文件可执行"
fi

6、test命令

test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试

由于和上面许多运算符类似,也将其放到运算符下了

test 条件语句可以相当于[ 条件语句 ],也就是test命令不需要加上[ ]

(1).数值测试

运算符 说明 使用示例
-eq 相等 test $a -eq $b
-ne 不等 test $a -ne $b
-gt 大于 test $a -gt $b
-lt 小于 test $a -lt $b
-ge 大于等于 test $a -ge $b
-le 小于等于 test $a -le $b

使用示例

a=15
b=20# 相等
if test ${a} -eq ${b}
thenecho "a==b"
fi# 不等【true】
if test ${a} -ne ${b}
thenecho "a!=b"
fi

(2).字符串测试

运算符 说明 使用示例
= 相等 test $a = $b
!= 不等 test $a != $b
-z 长度为0 test -z "$a"
-n 长度非0 test -n "$a"
非空 test $a

使用示例

a="  "
b="123a"
c="123a"# 【true】
if test "${b}" = "${c}"
thenecho "yes1"
fi# 【true】
if test "${a}" != "${c}"
thenecho "yes2"
fi# 【false】
if test -z "${a}"
thenecho "yes3"
fi# 【true】
if test -n "${a}"
thenecho "yes4"
fi# 【true】
if test "${a}"
thenecho "yes5"
fi

(3).文件测试

运算符(大致使用格式) 说明
-b file 检测file是否是块设备文件
-c file 检测file是否是字符设备文件
-d file 检测file是否是目录
-f file 检测file是否是普通文件
-S file 检测file是否为Socket
-L file 检测file是否为符号链接
-g file 检测file是否设置了SGID位
-k file 检测file是否设置了粘着位(Sticky Bit)
-u file 检测file是否设置了SUID位
-p file 检测file是否有名管道
-r file 检测file是否可读
-w file 检测file是否可写
-x file 检测file是否可执行
-s file 检测file是否非空
-e file 检测file是否存在

使用示例

# 【全部为true】if test -w test.sh
thenecho "文件可写"
fiif test -x test.sh
thenecho "文件可执行"
fi

(4).组合逻辑运算符

Shell 还提供了-a、或-o、非!三个逻辑操作符用于将测试条件连接起来

其优先级为: ! > -a > -o

使用示例

# 【true】
if test ! -S test.sh -a -w test.sh
thenecho "yes1"
fi

八、流程控制语句

1、条件判断语句

(1).if语句

一般格式如下:

if 条件表达式
then命令1命令2
elif 条件表达式2
then命令3命令4
else命令5命令6
fi

简单示例

a=1
b=2
c=3# 【true】
if [ $((--a)) == 0 ]
thenecho "yes"
fi# 【false】
if [ ${b} -ge ${c} ]
thenecho "b >= c"
# 【true】
elif [ $((a--)) == 0 ]
thenecho "b < c && a-- == 0"
# 【false】
elseecho "b < c && a-- != 0"
fiecho ${a} # -1

(2).case语句

一般格式如下:

case 值 in
模式1)命令1命令2;;
模式2)命令3命令4;;
*)命令5命令6;;
esac

注:
\qquad① 双分号;;作为每个分支的结束,而不是break
\qquad② 在模式匹配中,不加双引号可以使用*?等通配符

Tips:有关通配符的介绍,推荐下面几篇博文
\qquadLinux之通配符
\qquadLinux通配符和正则表达式

简单示例

a=123
b=123
c=123
d=124# 输出:匹配"123"
case ${a} in
1)echo "匹配\"1\"";;
123)echo "匹配\"123\"";;
*)echo "匹配default——*";;
esac# 输出:匹配*3
case ${b} in
1)echo "匹配\"1\"";;
*3)echo "匹配\"*3\"";;
*)echo "匹配default——*";;
esac# 输出:匹配default——*
case ${c} in
1)echo "匹配\"1\"";;
"*3")echo "匹配\"*3\"";;
*)echo "匹配default——*";;
esac# 输出:匹配default——*
case ${d} in
1)echo "匹配\"1\"";;
*3)echo "匹配\"*3\"";;
*)echo "匹配default——*";;
esac

2、循环语句

(1).for循环

一般格式如下:

for 变量 in 可迭代对象
do命令1命令2
done

无限循环

for (( ; ; ))
do命令
done

简单示例

for var in 1 2 3 4 5
doecho ${var}
done
# 输出:1(换行)2(换行)3(换行)4(换行)5(换行)for filename in `ls`
doecho ${filename}
done
# 输出:test.sh(换行)

(2).while循环

一般格式如下:

while 条件表达式
do命令
done

可以把read命令放入while语句的条件表达式,循环读取键盘输入(直到输入Ctrl + D

while read 变量
do命令
done

无限循环格式

# 格式1
while true
do命令
done# 格式2
while :
do命令
done

简单示例

a=1while [ ${a} -lt 10 ]
dolet a+=3echo ${a}
done# 【输出】
# 4
# 7
# 10while read -p "请输入你的名字(输入Ctrl+D结束):" abc
doecho "你的名字是${abc}"
done# 【使用案例】
# 请输入你的名字(输入Ctrl+D结束):excious
# 你的名字是excious
# 请输入你的名字(输入Ctrl+D结束):dinggou
# 你的名字是dinggou
# 请输入你的名字(输入Ctrl+D结束):

(3).until循环

一般格式如下:

until 条件表达式
do命令
done

本质上和while是等效的(并不像其他语言的do while循环),一般while循环优于until循环

简单示例

a=-1until [ ${a} == 0 ]
doecho $((++a))
done# 【输出】
# 0

(4).跳出循环

break跳出整个循环,退出循环体
continue跳出某次循环,继续下一次循环

简单示例

a=10
while [ ${a} -ge 0 ]
dolet a--# 判断偶数if [ $((a%2)) == 0 ]thenbreakfiecho ${a}
doneecho "-------"b=10
while [ ${b} -ge 0 ]
dolet b--# 判断偶数if [ $((b%2)) == 0 ]thencontinuefiecho ${b}
done# 【输出】
# 9
# -------
# 9
# 7
# 5
# 3
# 1
# -1

九、函数

函数的格式如下:

# 函数定义
[ function ] 函数名 [ () ]
{函数体[ return 0-255间的整数值 ]
}# 函数调用
函数名 [ 参数列表 ]

注:
\qquad① 不写return语句,将把函数体内最后一条命令的返回值作为函数的返回值
\qquad② 调用函数后,通过$?获取函数的返回值
\qquad③ 向函数传参的格式与 向shell脚本传参 的格式相同,函数体内$*等获得的是传入函数的参数而非传入shell脚本的参数

简单示例

mytest()
{cnt=0for arg in $*doecho ${arg}let cnt++donereturn ${cnt}
}mytest 12 34 545
echo $?# 使用示例:
# ./test.sh 565 68 53
# 12
# 34
# 545
# 3

十、输入/输出重定向

输入/输出重定向的指令如下:

命令 说明
命令 > file 将命令的输出重定向到file文件中(创建/覆盖)
命令 >> file 将命令的输出重定向到file文件中(创建/追加)
命令 < file 将命令的输入重定向到file文件中
<< tag 将开始标记tag和结束标记tag之间的内容作为输入(这种称为shell中的Here Document

一般情况下,每个 Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,默认从stdin读取数据
  • 标准输出文件(stdout):stdout 的文件描述符为1,默认向stdout输出数据
  • 标准错误文件(stderr):stderr的文件描述符为2,向stderr流中写入错误信息

默认情况下,命令 > filestdout 重定向到 file命令 < filestdin 重定向到 file

简单示例

# 命令的结果重定向到文件
who > test.txt# 从文件输入参数到命令
wc -l < test.txt# 同时为输入和输出进行重定向
wc -l < test.txt > test2.txt# 长自定义输入
wc -l << tag
> tgis
> ewi
> ee
> 134
>
> 231
> tag

示例截图
\qquad

Tips:
\qquad如果不希望命令的结果在屏幕上显示,可以将命令的输出结果重定向到/dev/null这一文件
\qquad/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到

十一、文件包含

在Shell中,可以使用文件包含,即在一个sh脚本中引用另一个sh脚本的内容

其格式如下

# 方式1
. 脚本位置# 方式2
source 脚本位置

注:
\qquad被引用的脚本文件并不需要拥有可执行权限

简单示例

  • test.sh文件

    test1="yes, this is test1"
    echo "test.sh loaded"
    
  • test2.sh文件
    . test.shsource test.shecho ${test1}
    

示例截图
\qquad

《Linux编程》学习笔记 ·003【Shell编程】相关推荐

  1. 嵌入式Linux基础学习笔记-文件IO编程-I/O多路复用

    实验内容:多路复用-I/O操作及阻塞 编程实现文件描述符集合的监听 multiplex_poll.c文件编写: /* multiplex_poll.c */ #include <fcntl.h& ...

  2. 嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)

    文件操作仿真FIFO,实现生产者-消费者运行模型 编程实现生产者程序producer.c,创建仿真FIFO结构文件(普通文件),按照给定的时间间隔向FIFO文件写入自动生成的字符(自定义),生产周期及 ...

  3. 嵌入式Linux基础学习笔记-文件IO编程-文件锁(1)

    文件锁-文件共享 共享资源竞争问题的解决方法:文件锁. 文件锁包括 建议性锁 要求每个上锁文件的进程都要检查是否有锁存在,并且尊重 已有的锁 强制性锁 由内核执行的锁,当一个文件被上锁进行写入操作的时 ...

  4. TCP/IP网络编程 学习笔记_1 --网络编程入门

    前言:这个系列网络编程教程实例代码是在Xcode上运行的,MacOSX,是一个基于UNIX核心的系统,所以基于Linux的网络编程代码一般可以直接在Xcode上运行,如果要移植到Windows其实就只 ...

  5. python编程学习笔记列表_python编程:从入门到实践学习笔记-函数

    Python学习资料或者需要代码.视频加Python学习群:516107834 定义函数 举个简单的例子 由上所示,关键字def定义一个函数,后面跟着函数名以及用来输入参数的括号,定义以冒号结束,而p ...

  6. shell脚本编程学习笔记1(xdl)——shell基础与Bash基本功能()

    shell脚本编程学习笔记1--shell基础与Bash基本功能 1,简介: 1,Shell就是一个命令行解释器,用以连接输入设别和内核. 2,Shell是解 释执行的脚本语言,在Shell中可以直接 ...

  7. 《Linux Shell编程学习笔记之一》

    <Linux Shell编程学习笔记之一> 前言 由于自己一直在Windows上面编程,用linux用的比较少,学习linux还是本科大二学的一点点知识.因此自己就准备花点时间来熟悉下li ...

  8. Linux Shell编程学习笔记(4)

    Linux Shell编程学习笔记(2015-7-20) 分类:linux shell   今天学习了Linux Shell中的控制结构.其实大多数语言的控制结构这一块都是基本类似的,有了C语言的基础 ...

  9. Linux Shell编程学习笔记(2)

    Linux Shell编程学习笔记(2015-7-12) 分类:linux shell Shell变量 一:关于Shell变量   Shell是一种弱类型的语言,变量存储的一切值都是字符串.Shell ...

  10. Linux Shell编程学习笔记(3)

    Linux Shell编程学习笔记(2015-7-19) 分类:linux shell 一:位置参数和特殊变量   什么是位置参数?   位置参数也叫位置变量,是运行shell脚本程序时,命令行she ...

最新文章

  1. 从0到1,从概念到国际标准,蚂蚁共享智能凭什么?
  2. outlook搜索不到历史邮件内容
  3. P3731 二分图匹配必经边
  4. 概念验证:玩! 构架
  5. LeetCode 2201. 统计可以提取的工件(哈希)
  6. [转载]保护 ASP.NET 应用程序的安全
  7. 用开源代码如何建立网站_在开源上建立自举业务
  8. d3 v5 api select
  9. 【poj3375】 Network Connection
  10. [导入]给老家新楼的对联
  11. Cannot resolve table 't_daily'
  12. TensorFlow精进之路(一):Softmax回归模型训练MNIST
  13. Unidac连接出错:命名管道提供程序:管道的另一端上无任何进程.
  14. LapStyle - 基于拉普拉斯金字塔的高质量风格化方法 | CVPR2021
  15. Robo 3T 使用教程
  16. Win7强制删除文件或文件夹
  17. mac下配置subl启动sublime text 编辑器
  18. PTGUI全景合成软件使用教程之控制点设置
  19. 嵌入式属于人工智能吗?
  20. 解决时间插件mobiscroll在使用过程中的一个小缺陷

热门文章

  1. mac java连通r_MacOS安装rJava
  2. mongodb空间查询java,java查看mongodb集合表空间大小
  3. 台达ms300变频器使用手册中文_台达变频器:满足未来驱动需求
  4. python定时器 是线程吗_定时器中断线程python
  5. 哈工大理论力学第八版电子版_理论力学哈工大第八版1第一章思考题课后题
  6. Python之对list进行切片
  7. 洛谷 | P1010 幂次方
  8. NumPy————NumPy广播机制的学习笔记
  9. PostgreSQL and SQLAlchemy [ubuntu]
  10. stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发