bash-learn

shell学习记录

Posted by Youga on April 14, 2018

shell 学习记录。

shall 运行

文件以#!/bin/bash开头,/bin/bash 指调用的程序

  • 直接运行
chmod +x ./test.sh  # 使脚本具有执行权限
./test.sh           # 执行脚本
test.sh             # 在PATH中寻找test.sh的脚本
  • 作为解释器参数运行
/bin/sh test.sh
/bin/php test.php

变量

  • 定义变量 使用变量时,{}可以选择加或者不加,仅仅作为变量名边界区分
your_name="runoob.com"      # 定义
echo $your_name             # 变量使用,{}作为变量边界
echo ${your_name}
echo "I am good at ${skill}Script"
# 将变量设置为只读,再次赋值报错
readonly your_name
  • 删除变量
unset variable_name
# !!不能删除只读变量

获取脚本参数

echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

用来处理参数的特殊字符:

  • $# 传递到脚本的参数个数
  • $* 以一个单字符串显示所有向脚本传递的参数。
  • $$ 脚本运行的当前进程 ID 号
  • $! 后台运行的最后一个进程的 ID 号
  • $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如”$@”用「”」括起来的情况、以”$1” “$2” … “$n” 的形式输出所有参数。
  • $- 显示 Shell 使用的当前选项,与 set 命令功能相同。
  • $? 显示最后命令的退出状态。0 表示没有错误,其他任何值表明有错误。

数组

  • 定义
array_name=(value0 value1 value2 value3)
# 或者
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
  • 使用
${数组名[下标]}
# @符号可以获取数组中的所有元素
echo ${array_name[@]}
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

for

for file in `ls /etc`
# 或
for file in $(ls /etc)
# 完整
for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

字符串操作

# 获取字符串长度
string="abcd"
echo ${#string} #输出 4

# 提取子字符串
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

# 查找子字符串
# 查找字符 "i 或 s" 的位置:
string="runoob is a great company"
echo `expr index "$string" is`  # 输出 8

shell 运算

  • 数学运算
    原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr。
val=`expr 2 + 2`
echo "两数之和为 : $val"
# 乘法运算需要在运算符前加 \
val=`expr $a + $b - $c \* $d / $e % $f`

echo `expr 1 == 1`  # 打印 1
echo `expr 1 != 1`  # 打印 0

#  [] 执行基本的算数运算
result=$[a+b] # 注意等号两边不能有空格
if test $[num1] -eq $[num2]
  • 关系运算

    	关系运算符只支持*数字*,不支持字符串,除非字符串的值是数字。
    	输出 true,false
    	- -eq	是否相等
    	- -ne	判断是否不相等
    	- -gt	左边的数是否大于右边的
    	- -lt	检测左边的数是否小于右边
    	- -ge	检测左边的数是否大于等于右边的
    	- -le	检测左边的数是否小于等于右边的
    
  • 布尔运算

    	- ! 非运算
    	- -o 或运算
    	- -a 与运算
    
  • 逻辑运算符 - && 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] -   逻辑的 OR [[ $a -lt 100   $b -gt 100 ]]
  • 字符串运算符

    	|运算符|说明|举例|
    	| - | :-: | -: |
    	|=|检测两个字符串是否相等|[ $a = $b ]  |
    	|!=|是否不相等|[ $a != $b ]|
    	|-z|检测字符串长度是否为0|[ -z $a ]|
    	|-n|检测字符串长度是否不为0|[ -n $a ]|
    	|str|检测字符串是否为空|[ $a ]|
    
  • 文件测试运算符
    文件测试运算符用于检测 Unix 文件的各种属性。
    file=”/var/www/runoob/test.sh”

    |操作符|说明|举例
    |-|:-:|-|
    -b file|检测文件是否是块设备文件|[ -b $file ] 返回 false。
    -c file|检测文件是否是字符设备文件|[ -c $file ] 返回 false。
    -d file|检测文件是否是目录|[ -d $file ] 返回 false。
    -f file|检测文件是否是普通文件(既不是目录,也不是设备文件)|[ -f $file ] 返回 true。
    -g file|检测文件是否设置了 SGID 位|[ -g $file ] 返回 false。
    -k file|检测文件是否设置了粘着位(Sticky Bit)|[ -k $file ] 返回 false。
    -p file|检测文件是否是有名管道|[ -p $file ] 返回 false。
    -u file|检测文件是否设置了 SUID 位,|[ -u $file ] 返回 false。
    -r file|检测文件是否可读|[ -r $file ] 返回 true。
    -w file|检测文件是否可写|[ -w $file ] 返回 true。
    -x file|检测文件是否可执行|[ -x $file ] 返回 true。
    -s file|检测文件是否为空(文件大小是否大于0)|[ -s $file ] 返回 true。
    -e file|检测文件(包括目录)是否存在,|[ -e $file ] 返回 true。
    

以上,也可以使用test表达式,如:

if [ $a -le $b ]
# 写成
if test $a -le $b

echo 输出

# 输出定向到文件
echo "It is a test" > myfile
# 打印日期
echo `date`

read 输入

read firstStr secondStr
echo "第一个参数:$firstStr; 第二个参数:$secondStr"
# 输入控制
read -p "请输入密码:" -n 6 -t 5 -s password
echo "\npassword is $password"
# -p 输入提示文字
# -n 输入字符长度限制(达到6位,自动结束)
# -t 输入限时
# -s 隐藏输入内容

printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

  • %s %c %d %f 都是格式替代符
  • %-10s 指一个宽度为 10 个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
printf "Hello, Shell\n"
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 # 输出:郭靖 男 66.12

shell 流程控制

以下,循环控制可以使用break,continue

  • if
if condition1
then
    commands
elif condition2
then
    commands
else
    commands
fi
  • for
// example1
for var in item1 item2 ... itemN
do
    command1
    ...
done
# 写成一行:
for var in item1 item2 ... itemN; do command1; command2… done;

// example2
# 依次打印0,1,2,3,4
for ((a=0;a<5;a++));do
echo $a
done
  • while
// example1
while condition
do
    command
done
// example2
# 依次打印 1,2,3,4,5
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
  • until
# 条件不满足的时候运行
until condition
do
    command
done
  • case
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    *)  echo '你没有输入 1 到 2 之间的数字'
    ;;
esac

函数

  • 定义

不带任何参数!!
return 返回,如果不加,将以最后一条命令运行结果,作为返回值

function A(){
	// ...
}
# 或者
A(){
	// ...
}
  • 调用
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 param2

重定向

命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command » file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n » file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
« tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

cat A.txt
# 输出:abcdefg
echo "菜鸟教程:www.runoob.com" > A.txt
cat A.txt
# 输出:菜鸟教程:www.runoob.com
echo "菜鸟教程:www.runoob.com" >> A.txt
cat A.txt
# 输出:菜鸟教程:www.runoob.com \n 菜鸟教程:www.runoob.com

文件包含

. filename   # 注意点号(.)和文件名中间有一空格
# 或
source filename

// example
# test1.sh 文件
url="http://www.runoob.com"
# test2.sh 文件
. ./test1.sh
# 或者
source ./test1.sh
echo "菜鸟教程官网地址:$url"

命令大全

shell 命令大全