linux shell攻略学习笔记一 基础篇

1.#!/bin/bash 

shebang 可以自定义 比如 #!/bin/bash +x 就会打印出执行日志

linux中 \0 代表null
echo –e “1\n2\n3”    会转义其中的\n,生成3行数据
$! 保存着最近一个后台进程的PID
$? 是最后一个命令的执行状态 0或1 (如果函数有return整数,那拿到的就是整数)
$# 传递给脚本的参数个数
$$  当前shell进程的ID
sleep 1   单位秒,不需要加括号。
Wait    要想等所有子进程结束之后 再终止脚本,就得使用wait命令。
touch –d  可以造假
grep “^l” 可以过滤出软连接文件,^表示以xx起始的字符串。
echo 'Text through stdin' | catfile.txt   这里的-是echo输出的作为管道后的stdin

2.命令序列界定

在Bash中,每个命令或是命令序列是通过使用分号或换行符来分隔的。

要么换行要么加分号;比如: $ cmd1 ; cmd2

它等同于:     $ cmd1

      $ cmd2

3.printf

  • %s、%c、%d和%f都是格式替换符;
  • %-5s指明了一个格式为左对齐且宽度为5的字符串替换(-表示左对齐)。如果不用-指定对 齐方式,字符串就采用右对齐形式。
  • 宽度指定了保留给某个变量的字符数。对Name而言,保留 宽度是10。因此,任何Name字段的内容都会被显示在10字符宽的保留区域内,如果内容不足10 个字符,余下的则以空格符填充。
  • 对于浮点数,可以使用其他参数对小数部分进行舍入。 对于Mark字段,将其格式化为%-4.2f,其中.2指定保留2个小数位。

4.赋值与相等

注意,var = value不同于var=value。把var=value写成var = value是一个常见的错误, 但前者是赋值操作,后者则是相等操作。

5.export

export PATH="$PATH:/home/user/bin" 也可以使用
$ PATH="$PATH:/home/user/bin"
$ export PATH

导出函数
export -f fname

6. 字符串长度

length=${#var}

7.数学运算

普通的变量赋值方法定义数值,这时,它会被存储为字符串

定义 no1=4; no2=5;

Let

变量前不需要加$符号,运算符前后也不需要加空格

let result=no1+no2
echo $result

$[]

在[]中也可以使用$前缀,也可以不用$前缀;但是运算符前后需要加空格

result=$[ no1 + no2 ]
result=$[ $no1 + 5 ]

$(( ))

同上; 可以加$,也可以不加;运算符号前后需要空格

result=$(( no1 + 50 ))
result=$(( $no1 + 50 ))

Expr

变量前必须加$,运算符号前后需要空格

result=`expr 3 + 4`
result=$(expr $no1 + 5)

Bc

高级运算,看demo是需要用echo 和管道符参与运算;有的linux不支持

no=54;
result=`echo "$no * 1.5" | bc`
echo $result
81.0
 
echo "scale=2;3/8" | bc 0.37
scale设置小数精度
no=100
echo "obase=2;
$no" | bc
输出1100100
no=1100100
echo "obase=10;ibase=2;$no" | bc
输出100 
Obase和ibase代表输出进制和输入进制

计算平方以及平方根
echo "sqrt(100)" | bc
echo "10^10" | bc

8.文件描述符及重定向

0 —— stdin(标准输入)。
1 —— stdout(标准输出)。
2 —— stderr(标准错误)。

cmd >stderr.txt  正常写入文件
cmd 2>stderr.txt 1>stdout.txt  不同日志追加到不同文件
cmd 2>&1 output.txt   2和1追加到一个文件
cmd &> output.txt     2和1追加到一个文件

文件黑洞、垃圾桶  /dev/null

9.tee

执行命令的时候,顺便copy一份为本地文件;tee –a 是追加,默认是覆盖
cat a* | tee out.txt | cat –n
cat a* | tee –a out.txt | cat -n

10.文件描述符

文件描述符类似java中的文件引用(我自己觉得)
exec 3<input.txt  #引用
cat<&3     #读取

截断模式

$ exec 4>output.txt
$ echo newline >&4
$ cat output.tx

追加模式

$ exec 5>>input.txt
$ echo appended line >&5
$ cat input.txt
newline
appended line

11.数组

定义
array_var=(1 2 3 4 5 6)
#这些值将会存储在以0为起始索引的连续位置上
另外,还可以将数组定义成一组“索引-值”:
array_var[0]="test1"
array_var[1]="test2"
。。。。
使用
echo ${array_var[0]}
echo ${array_var[$var]}     #变量
echo ${array_var[*]}           打印所有
echo ${array_var[@]}           打印所有
echo ${#array_var[*]}          打印数组length

12.关联数组(hashmap)

定义
$ declare -A ass_array
使用
ass_array=([index1]=val1 [index2]=val2) 
ass_array[index1]=val1
ass_array'index2]=val2
Keys收集map的keys
echo ${!array_var[*]}   数组前用!号
echo ${!array_var[@]}   数组前用!号

get获取value值   

====== echo ${array_var[key]}

13.别名

alias new_command='command sequence'
不用别名,用原始命令
\command
用途:rm 改为先扔到垃圾桶,在rm

14,.时间日期操作

纪元时间(单位秒)
date +%s
1290047248 
date --date "Thu Nov 18 08:07:21 IST 2010" +%s
1290047841

参数
Date “+ 参数1  参数2”
date "+%d %B %Y"
20 May 2010

15.Time

Time  sh脚本路径
得到执行脚本所花 费的时间

16.脚本调试

bash -x script.sh
 
使用set -x和set +x对脚本进行部分调试
for i in {1..6};
 do
   set –x
   echo $i
   set +x
done
echo "Script executed"

set –x:在执行时显示参数和命令。
set +x:禁止调试。
set –v:当命令进行读取时显示输入。
set +v:禁止打印输入。

 

#!/bin/bash –xv 调试脚本直接在脚本内写shebang

17.函数

function fname()
{
     statements;
 }
或者:
 fname()
{
    statements;
 }

可以不要function关键字;
函数定义不和java一样,还需要定义函数参数,直接传入用$1,$2接受。
调用函数
Fname                                 无参调用
fname arg1 arg2               含参调用
函数内使用参数
$@ 所有参数
$* 所有参数(这个用的少)
$0 所有参数
 
cmd;
echo $?;
$?是上一步的执行结果0代表成功
函数返回值
sum(){
res=$[ $1 + $2 ]
echo "$res"
}

the_sum=$(sum 5 6)

echo "the_sum=${the_sum}"

输出the_sum=11

  1. 使用echo可以返回参数,返回多个参数用全局变量来接吧
  2. Return 只能返回数值,需要用$?来接收;例子如下:
sum(){
    res=$[ $1 + $2 ]
    return 100
}
the_sum=$(sum 5 6)
echo "the_sum=$?"
函数的跨脚本调用

场景:和java类似,有些通用的工具类进行封装后在别的地方就可以调用了。

Fun.sh内容:

sum(){
    res=$[ $1 + $2 ]
    echo "$res"
}

Test.sh脚本中调用sum

#!/bin/bash
source ./fun.sh
val=$(sum 4 3)
echo "val="${val}

18.执行命令保留换行符

假设我们使用子shell或反引用的方法将命令的输出读入一个变量中,可以将它放入双引号 中,以保留空格和换行符(\n)。

$ cat text.txt
1
2
3
$ out=$(cat text.txt)
$ echo $out
1 2 3

 理论上换行符没了;但是我试下面的命令(加双引号)没有效果

$ out="$(cat tex.txt)"
$ echo$out
1
2
3

19.Read

一般情况:有当回车键按下的时候,才标志着输入完毕

read -n 2 var   #读取2个字符结束
read -s  var   #用无回显的方式读取密码
read -p "Enter input:" var     #显示提示信息
read -t 2 var     #在2秒内将键入的字符串读入变量var

read -d ":" var   #自定义结束符号
hello: #var 被设置为 hello

20. 运行命令直至执行成功

repeat()
{
while true
 do
    $@ && return
 done
}

主要就是$@ && return  $@读取输入参数,&& return 代表执行成功就返回。

 21. 字段分隔符

IFS是存储定界符的环境变量。它是当前 shell环境使用的默认定界字符串。

IFS的默认值为空白字符(换行符、制表符或者空格)。

读取csv文件: 

data="name,sex,rollno,location"

我们可以使用IFS读取变量中的每一个条目。

oldIFS=$IFS                  #将默认分隔符备份
IFS=, now,                    #修改默认分隔符
for item in $data;
do
     echo Item: $item
done
IFS=$oldIFS                   #还原默认分隔符

输出如下:
Item: name
Item: sex
Item: rollno
Item: location    

22.循环

echo {1..50}能够生成一个从1~50的数字列表。echo {a..z}或{A..Z}或{a..h}可以生

成字母列表

For循环
for var in list;
do
 commands; #使用变量$var
done循环

java 风格也可以
for((i=0;i<10;i++))
{
 commands; #使用变量$i
}
While循环
while condition
do
 commands;
done
until循环

现在的语言里很少见until了,以前汇编语言里有。

x=0;
until [ $x -eq 9 ]; #条件是[$x -eq 9 ]
do
 let x++; echo $x;
done

23.if条件控制

if condition;
then
 commands;
else if condition; then
 commands;
else
 commands;
fi
逻辑运算符判断(相当于if的简化版)
[ condition ] && action;           # 如果condition为真,则执行action;
[ condition ] || action;              # 如果condition为假,则执行action。

24.运算比较

一定要注意在[或]与操作数之间有一个空格。如果 忘记了这个空格,脚本就会报错

[ $var -eq 0 ] #当 $var 等于 0 时,返回真

-gt:大于。
-lt:小于。
-ge:大于或等于。
-le:小于或等于。
 
多个条件
[ $var1 -ne 0 -a $var2 -gt 2 ]   #使用逻辑与-a
[ $var1 -ne 0 -o var2 -gt 2 ]       #逻辑或 –o
或者
[ 5 = 5 ] && [ 3 = 3 ]

25.字符串比较

使用字符串比较时,最好用双中括号,因为有时候采用单个中括号会产生错误

[[ $str1 = $str2 ]]     #单等号
或者
[[ $str1 == $str2 ]]      #双等号  双等号和单等号效果一样
[[ $str1 != $str2 ]]      #不等

非空校验

[[ -z $str1 ]]:如果str1包含的是空字符串,则返回真。
[[ -n $str1 ]]:如果str1包含的是非空字符串,则返回真。
 
if [[ -n $str1 ]] && [[ -z $str2 ]] ;  #多条件判断
then
 commands;
fi

 

test 可以替换[[]]和[],这样做是避免使用太多中括号。

[]内布尔值无法赋值给变量的问题
`[ 5 = 3 ] ; echo $?`
`[ 5 = 3 ] && echo $?`
不能直接用var=[ 5 = 3 ]赋值,只能这样[ 5 = 1 ] ; v=$?; echo $v
posted @ 2019-12-20 21:39  Nucky_yang  阅读(447)  评论(0编辑  收藏  举报