shell 学习
hello world
编辑shell文件 vim hello.sh
#!/bin/bash
# This is a hello world
echo "hello world"
保存退出,加运行权限chmod u+x hello.sh
(当前用户运行权限 ,a+x 所有人运行权限), 运行./hello.sh
例子说明:
#!
说明文件类型,类似windows文件后缀(.exe), linux 根据 #! 以及后面字符串信息确定文件类型(man magic
命令 以及/usr/share/magic
了解更多)/bin/bash
表明文件是一个bash程序,需要/bin下bash程序解释执行,使用locate bash
或find / -name bash 2>/dev/null
或whereis bash
三个命令找出bash所在位置,如果没有需要自己安装bash安装包- bash中绝大多数语句没有分号
如何执行
bash hello.sh
或 shhello.sh
显式执行chmod u+x hello.sh
,运行./hello.sh
bash被执行实际是linux另外开了一个进程来运行的。
变量
script 设置的变量名称: $0 /path/scriptname 命令名称,$1...$n 参数
$#
:代表后接的参数『个数』,以上面为例这里显示为『 4 』;$@
:代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);$*
:代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字符,默认为空格键.
Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则
- 首个字符必须为字母(a-z,A-Z) 或者_
- 中间不能有空格,可以使用下划线(_)
- 不能使用其他标点符号
需要给变量赋值时,写成变量名=值
。 注意:不能在"="两边留空格
取用一个变量的值,只需在变量名前面加一个$
可以和其他文字混起来书写
num=2
echo "this is the ${num}nd"
shell的默认赋值是字符串赋值
var=1
var=$var+1
echo $var
# 打印出来的不是2而是1+1,要达到目的用下面的替换
let "var+=1"
var="$[$var+1]"
((var++))
var=$(($var+1))
var="$(expr "$var" + 1)" #不建议使用
var="`expr "$var" + 1`" #强烈不建议使用,注意加号两边的空格,否则还是按照字符串的方式赋值,`为Esc下方的`,而不是单引号'
let表示数学运算,expr用于整数值运算,每一项用空格隔开,$[]将中括号内的表达式作为数学运算先计算结果再输出。
使用date 进行文档建立(test.2016-12-13.dat)
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示信息
read -p "Please input your filename: " fileuser # 提示使用者输入
# 2. 为了避免使用者随意按 Enter ,利用变量功能分析文件名是否有设定?
filename=${fileuser:-"filename"} # 开始判断有否配置文件名
# 3. 开始利用 date 指令来取得所需要的文件名了;
date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期
date3=$(date +%Y%m%d) # 今天的日期
file1=$filename${date1} # 底下三行在配置文件名
file2=$filename${date2}
file3=$filename${date3}
# 4. 将档名建立吧!
touch "$file1" # 底下三行在建立档案
touch "$file2"
touch "$file3"
关于filename=${fileuser:-"filename"}的用法,用来判断fileuser是否已经赋值。:-是一起的;fileuser 如果有值的话,就用所拥有的值赋予给filename变量;无值的话,就把filenname赋予给fileuser,再赋予给filename变量
shell 流控制
if 语句
if ....; then
....
elif ....; then
....
else
....
fi
通常用" [ ] "来表示条件测试,要确保方括号前后的空格,[$条件$]左右必须各敲一个括号($表示空格)
[ -f "somefile" ]
:判断是否是一个文件[-d “Directory”]
: 判断目录是否存在[ -x "/bin/ls" ]
:判断/bin/ls是否存在并有可执行权限[ -n "$var" ]
:判断$var变量是否有值[ "$a" = "$b" ]
:判断$a和$b是否相等
#!/bin/bash
if [ ${SHELL} = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but ${SHELL}"
fi
&& 和 || 操作符
-
command1 && command2
: &&左边的命令返回真(即返回0,成功被执行)后,&&右边的命令才能够被执行 -
command1 || command2
: ||则与&&相反。如果||左边的命令未执行成功,那么就执行||右边的命令;
case 语句
case ... in
...) do something here
;;
esac
#!/bin/bash
ftype="$(file "$1")"
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;; #每个类别结尾使用两个连续的分号来处理
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*) echo "File $1 can not be uncompressed with smartzip";; #最后一个变量内容都会用 * 来代表所有其他值
esac #最终的 case 结尾
select 语句
select表达式是bash的一种扩展应用,擅长于交互式场合。用户可以从一组不同的值中进行选择
select var in ... ; do
break;
done
.... now $var can be used ....
#!/bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break;
done
echo "You have selected $var"
while/for 循环
只要测试表达式条件为真,则while循环将一直运行。关键字"break"用来跳出循环,而关键字”continue”则可以跳过一个循环的余下部分,直接跳到下一次循环中。
while [ condition ] <==中括号内的状态就是判断表达式
do <==do 是循环的开始!
程序段落
done <==done 是循环的结束
for循环会查看一个字符串列表(字符串用空格分隔),并将其赋给一个变量
for var in ....; do
....
done
#!/bin/bash
for var in A B C ; do
echo "var is $var"
done
for var in "$@"; do // $@
包含有输入的所有命令行参数值 for var in "$*"; do // $*
意思是差不多的。但是只有一个字串。如果不加引号,带空格的参数会被截断
Shell里的一些特殊符号
1.*
:通配符,可以使用双引号和单引号防止扩展.
单引号更严格一些,它可以防止任何变量扩展;而双引号可以防止通配符扩展但允许变量扩展:
#!/bin/bash
echo $SHELL
echo "$SHELL"
echo '$SHELL'
#结果
/bin/bash
/bin/bash
$SHELL
2.\
转义字符
echo \*.jpg
echo \$SHELL
#结果
*.jpg
$SHELL
函数 function
function fname() {
程序段
}
函数没有必要声明。必须在执行之前出现定义就行
function 也是拥有内建变量,内建变量与shell很类似,函数名称代表示 $0 ,而后续接变量也是以 $1, $2... 来取代的
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
function printit(){
echo "Your choice is $1" # 这个 $1 必须要参考底下指令的下达
}
echo "This program will print your selection !"
case $1 in
"one")
printit 1 # 请注意, printit 指令后面还有接参数!
;;
"two")
printit 2
;;
"three")
printit 3
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
#结果
输入 sh test.sh one
结果 Your choice is 1
因为打印方法传递的参数是1.
调试
sh [-nvx] scripts.sh
- -n :不要执行 script,仅查询语法的问题;
- -v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
- -x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!