shell笔记

http://www.dooccn.com/shell/ (shell在线编程网站,也支持大量其他语言)
http://c.biancheng.net/shell/
http://www.runoob.com/linux/linux-shell.html
https://www.pstips.net/powershell-online-tutorials (powershell!!!)
(注意:PowerShell和bat文件没有关系;前者可以代替后者,见 https://www.cnblogs.com/ldy_ai/p/4729907.html)

本文主要研究Bourne Again Shell,即bash(/bin/bash);
(此外还有Bourne Shell即/usr/bin/sh或/bin/sh、C Shell即/usr/bin/csh、K Shell即/usr/bin/ksh等;)
(cat /etc/shells可以查看所有shell!!!)
(查看shell版本:echo $BASH_VERSION或bash --version)

若sh文件中第一行写了#!/bin/bash,则直接./test.sh即可;
若没写,可以执行 /bin/sh test.sh

echo $your_name和echo ${your_name}等价;

要想变量的作用域仅限于函数内部,可在定义时加上local命令,此时变量就是局部变量;(shell和js类似, 函数内部定义的变量,默认是全局变量;js需要加var才能变为局部变量;)

readonly XXX可以声明变量为只读;
unset XXX可以删除变量;(注意:它不能删除只读变量)
(declare -r n=10也可以声明变量为只读)

shell的字符串可以是单引号、双引号或无引号,区别是单引号无法定义变量;
(具体情况较为复杂和迷惑,总之双引号比单引号好;)

echo ${#string}#获取字符串长度
echo ${string:1:4}#截取子串
echo ${string:0-1:4}#表示从右边开始截取

#查找子串(字符i或o的位置,哪个先出现就计算哪个)
string=“runoob is a great site”
echo expr index "$string" io # 输出 4

#shell数组
array_name=(value0 value1 value2 value3)
或array_name[0]=value0单独赋值;
甚至ages=([3]=24 [5]=19 [10]=12),即无需挨个赋值,类型也可以不同;

注意:数组读取必须加大括号,如echo ${array_name[1]}
获取全部元素,执行echo ${array_name[@]}
获取数组长度,执行echo ${#array_name[@]}或echo ${#array_name[*]}
获取某个元素的长度,执行echo ${#array_name[n]}

echo {1…10}
time echo {1…100}
for a in {1…10};do echo $ a; done;
aNumList=$(seq 100); echo $aNumList

shell的单行注释和python一样;
shell的多行注释为:
:<<EOF (其中’:'可以去掉)
注释内容…
EOF (其中’EOF’也可以用别的符号,如单引号、感叹号、或任意字符串)

shell中捕捉传递的参数方式$0、$1、$2、$3…;
捕捉参数个数方式 $ #;
以单字符串捕捉所有参数方式$ *;
(此外还有$ $、 $ !、 $ @、 $ -、 $ ?等;其中 $ @和 $ *比较类似;
$ !和 $ $ 都与进程id有关; $?和退出状态有关;)

shell利用expr等工具实现简单的数学运算,如:
val=expr 2 + 2
echo “两数之和为 : $ val”
注意:2 + 2之间必须有空格;
(除了expr,还有bc、let、awk也可用于数值计算;其中bc和awk可以浮点运算;)
(也可以直接用((a=3+5, b=a+10)) echo $ a $b;c= $ ((4+8, a+b)) echo $ c;注意:以最后一个表达式的结果作为整个(())命令的执行结果 )
(也可以使用echo $[3*5];注意不能没有echo!)
(bc非常强大,是一个任意精度的计算器语言;)
(注意:非数值类,比如字符串,千万不能用let!!!)

算术运算符:
expr $a + $bexpr $a - $bexpr $a \* $bexpr $b / $aexpr $b % $a、a=$b、[ $a == $b ]、 [ $ a != $ b ]
(乘法比较特别,需要转义;除法是整数之间的除法;)
注意: [ $a == $b ]必须有有空格;

用gawk或awk实现小数除法:
aa=11.1
bb=23.0
gawk -v x= $ aa -v y= $ bb ‘BEGIN{printf “%.3f\n”,x+y}’

#bc的demo1:
a=7.2
b=8
if [ echo "$a < $b"|bc -eq 1 ]
then
echo "$a < $b "
else
echo " $ a > $ b "
fi

#bc的demo2:
for((i=1;i<=10;i++))
do
echo $ i
j= $ (echo “$i*0.2-2.5”|bc)
echo $ j
done

关系运算符:
[ $a -eq $b ]、[ $a -ne $b ]、[ $a -gt $b ]、[ $a -lt $b ]、[ $a -ge $b ]、[ $a -le $b ]
(注意:只支持数字,不支持字符串)

布尔运算符:
[ ! false ]、[ $a -lt 20 -o $b -gt 100 ]、[ $a -lt 20 -a $b -gt 100 ]

逻辑运算符:
[[ $a -lt 100 && $b -gt 100 ]]、[[ $a -lt 100 || $b -gt 100 ]]
(逻辑运算符和布尔运算符啥区别?都是将多个表达式连在一起判断,难道只有两层括号的区别?)
(逻辑运算符是对test命令和布尔运算符的改进?去掉-o和-a,只能使用 || 和 &&;)
(推荐使用逻辑运算符即[[]] !!!)
([[ ]]对数字的比较不友好,建议使用if判断条件时,用(())处理整型数字,用[[ ]]处理字符串或者文件;)

字符串运算符:
[ $a = $b ]、[ $a != $b ]、[ -z a ] 、 [ − n &quot; a ]、[ -n &quot; a][n"a" ]、[ $a ]

文件测试运算符:
[ -b $file ]、[ -c $file ]、[ -d $file ]、[ -f $file ]、[ -g $file ]、[ -k $file ]、[ -p $file ]、
[ -u $file ]、[ -r $file ]、[ -w $file ]、[ -x $file ]、[ -s $file ]、[ -e $file ]

#从标准输入读取一个变量
read name
echo “$name It is a test”

printf和echo类似,但它不会自动加\n,它还能设定对齐、宽度等;
如printf “%-10s %-8s %-4.2f\n” 郭靖 男 66.1234

test命令可以对数值、字符和文件3方面进行测试;
(注意:它和关系运算符类似,不过它不加括号;如if test $[num1] -eq $[num2]和[ $a -eq $b ]对比)
(数值:-eq、-ne、-gt、-ge、-lt、-le;字符串:=、!=、-z、-n ;文件:-e、-f、-w、-x、-s、-d、-f、-c、-b)

##############

#shell打印一个目录的文件名
for file in ls /etc
do
echo $file
done

#for循环一种写法
for((i=1;i<=5;i++ ))
do

echo “这是第 $i 次调用”;

done
可以不加分号(done和for后面),但一定要加两层括号,且中间不能有空格;
shell虽然很灵活(比如没有python那样的对齐),但它有自己的坚持!!!

#for循环第二种写法
num1= $ [2*3]
num2= $ [1+5]
if test $[num1] -eq $[num2]
then
echo ‘两个数字相等!’
else
echo ‘两个数字不相等!’
fi

#for循环第三种写法
for loop in 1 2 3 4 5
do
echo “The value is: $loop”
done

#while循环
int=1
while(( $int<=5 ))
do
echo $int
let “int++”
done

#while无限循环
while : (或while true、for (( ; ; )) )
do
command
done

#until 循环
(until循环与while循环在处理方式上刚好相反;)
until condition
do
command
done

case in语句类似switch case,末尾要加esac,这点和if类似;
read aNum
case $aNum in
1 ) echo ‘你选择了 1’
;;
2 ) echo ‘你选择了 2’
;;
* ) echo ‘你没有输入 1 到 2 之间的数字’
;;
esac

shell的break和continue与其他语言相同;

shell的函数定义不用写def,调用不用加括号;
(参数不用写在函数括号中,直接用 $ 1、 $ n、$#等捕捉即可;)

Shell输入输出重定向:
n >& m#将输出文件 m 和 n 合并
n <& m#将输入文件 m 和 n 合并
(0是标准输入STDIN、1是标准输出STDOUT、2是标准错误输出STDERR)
(每个 Unix/Linux 命令运行时都会打开三个文件,STDIN、STDOUT和STDERR;文件描述符分别为0、1、2;)
(Unix程序默认从stdin读取数据、向stdout输出数据、向stderr流中写入错误信息;)

注意:cat words.txt | while read line使用的管道,会导致创建subshell,从而导致循环内的map无法赋值给循环外的map;
可以使用while read line 。。done < words.txt代替;
https://blog.youkuaiyun.com/ystyaoshengting/article/details/83240678 刷Leecode192也遇到相同的问题)

sort命令:
sort tmp.txt -t " " -k 2 -r
(文件每行有key value代表word及count,按照value逆序打印,分隔符为空格,以第二列作为key)
https://blog.youkuaiyun.com/monkeyduck/article/details/10097829

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值