Linux Shell 基本语法 ,编程接口不如sh

2020-03-28 作者:首页   |   浏览(60)
  1. shell程序命令:普通命令、内建命令。   
  2.    外部命令:可以在命令提示符处执行的命令。   
  3.    内建命令:在shell内部实现的,不能做为外部程序被调用。   
  4.    命令是内部还是外部的一般并没有多在的重要性,只是内部命令执行   起来效率更高一些。   
  5. shell程序设计中通常使用的命令:   
  6.     1、break命令   
  7.       使用这条命令能够从封闭的for/while/until循环中退出。还可加上数值参数来表示退出循环的层数(break 2),不加参数退出一层循环。   
  8. 例子:  
  9. #!/bin/sh  
  10. #This is a example for the instruction of "break"   
  11.   
  12. var1=1   
  13. var2=1   
  14. while [ var1 -le 10]   
  15. do  
  16.   while [ var2 -le 10]   
  17.   do  
  18.     echo "var1=${var1} var2=${var2}"  
  19.     var1=(($var2 + 1))   
  20.     if [ var2 -eq 8 ] ; then   
  21.       break 2   
  22.     fi   
  23.   done   
  24.   var2=(($var1 + 1))   
  25. done   
  26.   
  27. exit 0   

13.7.1 break命令

退出循环的一种简单方法。可以退出任意类型的循环,包括while和until。

下面几种情况可以使用break命令。

1.跳出单个循环

执行break时,它会尝试跳出当前正在执行的循环。

*  1 #!/bin/bash*

*  2 for var in 10 9 8 7 6 5 4 3 2 1*

*  3 do*

*  4         if [ $var -eq 5 ]*

*  5         then*

*  6                 echo "this is exec break;"*

*  7                 break*

*  8         fi*

*  9         echo "var = $var"*

* 10 done*

 

这个方法也适用于while和until循环。

 

2.跳出内部循环

处理多个循环时,break会自动终止你所在的最内层的循环。

内层循环终止了,外层循环依然会继续执行。

 

3.跳出外部循环

有时你在内部循环,但需要停止外部循环。break命令接受单个命令行参数。

break n

n指定了要跳出的循环层级。默认情况下n为1.表示跳出当前循环。

若为2,就表示跳出上一级的外部循环。

例子:

1 #!/bin/bash

*  2 for(( i=5; i>0; i-- ))*

*  3 do*

*  4         echo "outer loop: i = $i"*

*  5         for(( j = 0; j < 100; j++ ))*

*  6         do*

*  7                 echo "inside loop: j = $j"*

*  8                 if [ $j -eq 5 ]*

*  9                 then*

* 10                         break 2 # 跳出上一级循环*

* 11                 #       break # 跳出当前循环*

* 12                 fi*

* 13         done*

* 14 done*

 

【if条件:比较操作,if条件控制结构】

#!/bin/bash

a=10

if [ $a -gt 0 ]

then echo 1

else echo 2

fi

 

echo "you number is $ans"

13.3.2 使用多个测试命令

可以在while后面接多个测试命令,只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环

例子:

  1 #!/bin/bash

  2 # multicommand test

  3 var=2

  4 while echo "var = $var"

  5         [ $var -ge 0 ]  # -ge 相当于大于等于 >=

  6 do

  7         echo "this is inside the loop"

  8         var=$[ $var - 1 ]

  9 done

结果:

 图片 1

说明每次迭代中所有的命令都会执行,包括测试命令失败的最后一次迭代。

另外,如何指定多个测试命令。每个测试命令都出现再单独的一行上。

 

case命令

case 命令以列表导向格式检查单个变量的多个值。

case variable in 
pattern1 | pattern2) commands1 ;; 
pattern3) commands2;;
*) default commands;;
esac

case 命令将指定的变量与不同的模式进行比较。如果变量与模式匹配,shell 执行为该模式指定的命令。可以在一行中列出多个模式,使用竖条操作符将每个模式分开。星号是任何列出的模式都不匹配的所有值。

以下是一个使用case的实例:

dirs=`ls $sourceRoot/android | tr 'n' ' '`
for i in $dirs
do
sourceFold=$sourceRoot/android/${i}
case ${i} in 
out)
echo "skip ${i}";;
kernel|frameworks|vendor|build)
cp -rfu $sourceFold $workRoot/android
echo "copy ${i}";;
*) 
ln -sf $sourceFold $workRoot/android
echo "linking ${i}";;
esac
done

再让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如: 

file lf.gz 

这将返回: 

lf.gz: gzip compressed data, deflated, original filename, 

last modified: Mon Aug 27 23:09:18 2001, os: Unix 

下面有个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件: 

#!/bin/sh 
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 

您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。

也就是说,当我们运行: 

smartzip articles.zip 

$1 就是字符串 articles.zip

 

【while循环】

num=1

result=0

while [ $num -le 3 ]

do

result=$(($result+$num))

num=$((num+1))

done

 

echo $result

 

command

13.9.1 查找可执行文件

找出系统中有哪些可执行文件可供使用,只找PATH环境变量中所有的目录就行了

例子:

*  1 #!/bin/bash*

*  2 # find files in the PATH*

*  3 IFS=:*

*  4 for folder in $PATH   # 将各个目录放入folder中*

*  5 do*

*  6         echo "$folder"*

*  7         for file in $folder/*   # 迭代指定目录中的所有文件*

*  8         do*

*  9                 if [ -x $file ]  # 检查是否有可执行权限*

* 10                 then*

* 11                         echo "    $file"*

* 12                 fi*

* 13         done*

* 14 done*

 

对于Linux ,Bash ,Shell的概念问题

1.是
2.区别大,你会写bash shell不代表你会写c shell,不过我觉得你会写一个shell脚本
另一种你上手也很快,起码读懂应该问题不大。你可以先学bash shell因为用的比较多
而且可移植性强,bash 是shell的一种。
3.属于shell,只安装了bash shell就可以运行bash shell脚本,并不是针对某个系统或者发行版本。
shell这种东西可以随意安装的。你用习惯哪个shell,就算初装系统里没有,你也可以单独安装一个
4.给你推荐两本书
《Bash shell高级脚本指南》
《实战LINUX+SHELL编程与服务器管》

shell编程,可以说直接反应出你对linux命令掌握的熟练度问题,什么情况下用哪种命令更符合
你的工作需求,怎么简化脚本运行过程,优化脚本让它更有效率。
你在学习过程中必然会接触到sed,awk这种流编辑器。然后你还得学习sed,awk。
渐渐地估计你就该选择一门更强大的编程语言,而不仅限于写shell脚本,比如选perl.python,php.
C,或者什么语言...基本上都是这个过程。  

1 概念 bash(sh,pdsh扩充): GNU Bourne-Again Shell sh:Bourne Shell,编程优秀,用户交互不便。 csh:C Shell,编程接口不如sh,用户界...

echo "others"

13.3.1 while的基本格式

while test command

do

  other commands

done

关键在于test command的退出状态码要随着循环中运行的命令而改变。否则就会停不下来

例子:用方括号检查循环命令中用的shell的变量的值

*  1 #!/bin/bash*

*  2 i=10*

*  3 while [ $i -gt 5 ] # 相当于 >*

*  4 do*

*  5         echo "i = $i"*

*  6         i=$[ $i - 1 ]  # 不能用i--*

*  7 done*

 

if-then语句

在其他编程语言中,if 语句后面的对象是一个值为 TRUE 或 FALSE 的等式。 bash shell脚本中的 if 语句不是这样的。 bash shell 中的 if 语句运行在 if 行定义的命令。如果命令的退出状态是0(成功执行命令),将执行 then 后面的所有命令。如果命令的退出状态是0以外的其他值,那么then后面的命令将不会执行, bash shell 会移动到脚本的下一条命令。

 

格式:

  if command

  then

       commands

  fi

 

示例

#!/bin/bash
#  testing multiple commands in the then section
testuser=rich
if grep $testuser /etc/passwd
then
  echo The bash files for user $testuser are :
  ls -a /home/$testuser/.b*
fi

注意:在一些脚本中,可能会看到 if-then 语句的另一种形式:

if command; then

  commands

fi

在计值的命令末尾使用一个分号,可以将 then 语句包含在此行中,这更像是在其他一些编程语言中处理 if-then 语句的方式。

 

2.2.3        for循环

for var in [ list ];do

 statements

done

【PS】

var 变量的引用不使用$。

<list>的元素用空格分隔。

           

 

a=a+1

13.7.2 continue命令

提前终止某次循环中的命令,不会完全终止整个循环。

例子:

*  1 #!/bin/bash*

*  2 for(( i=0; i < 10; i++ ))*

*  3 do*

*  4         if [ $i -gt 4 ] && [ $i -lt 8 ]*

*  5         then*

*  6                 continue*

*  7         fi*

*  8         echo "haha i = $i"*

*  9 done*

注意:这个会跳过剩余的命令,如果在剩余的命令中要对测试条件变量进行改变就会出问题。这里需要留个心眼。

 

也可以通过命令行参数指定要继续执行哪一级循环。 continue n

 

*  1 #!/bin/bash*

*  2 for(( i=0; i < 5; i++ ))*

*  3 do*

*  4         echo "out loop; i = $i"*

*  5         for(( j=0; j<4; j++ ))*

*  6         do*

*  7                 echo "          inside loop +++ j = $j"*

*  8                 if [ $j -eq 2 ]*

*  9                 then*

* 10                         continue 2  #继续上一级循环还可以不接2,表示继续当前循环*

* 11                 fi*

* 12                 echo "          inside loop --- j = $j"*

* 13         done*

* 14 done*

 

注意break和continue的区别:

break用于完全结束一个循环,后面的循环也不执行了。

continue用来结束当前循环,后面的循环还会执行。

比如:

for(i = 0; i < 10; i++)

do

         if [ $i –eq 5]

         then

                   break   # 6 , 7 , 8 ,9 就都不会打印了,结束了。

# continue # 仅仅不打印5

         fi

echo “i = $i”

done

 

移位(shift) 

shift命令能够改变命令行参数的相对位置。使用 shift 命令时,默认将每个参数变量左移一个位置。

示例 

#!/bin/bash
# demonstrating the shift command

count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift
done

【Linux常用命令】

vi zzhdir

#!/bin/bash

ls –a

--执行

sh zzhdir

 

 执行这个命令时

13.1.3 从变量读取列表

将一系列的值都集中存储在了一个变量中,然后需要遍历变量中的整个列表。 

#!/bin/bash

# for test

name1="xcx1 xcx2 xcx3"

name2=$name1" xcx4"

#for name in xc'y "xcy'1 haha" xcy2 xcy3 xcy4 xcy5

for name in $name2

do

*        echo "Hi, My name is $name"*

done

echo "The last people is $name"

 

name2包含了用于迭代的标准文本值列表。注意。name2用了另一个复制语句向name2变量包含的以有列表中添(或者说拼接)加了一个值。

 

break 命令

break 命令是在处理过程中跳出循环的一种简单方法。

示例

#!/bin/bash
# breaking out of a for loop

for var1 in 1 2 3 4 5 6 7 8 9 10
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration number: $var1"
done
echo "The for loop is completed"

 

break 命令包括单独的命令行参数值

break n

示例

#!/bin/bash
# breaking out of an outer loop

for (( a=1; a<4; a++ ))
do
echo "Outer loop: $a"
for (( b=1; b<100; b++ ))
do
if [ $b -gt 4 ]
then
break 2
fi
echo " Inner loop: $b"
done
done

 

2.2.5        until循环

until [ condition ]

do

statements

done

 

 

done

13.1.4 从命令读取值

生成列表中所需值的另外一个途径就是使用命令的输出。

可以用命令替换来执行任何能产生输出的命令,然后在for命令中使用该命令的输出。

例子:

新建一个文件states,内容如下:

 图片 2

再建一个test2

#!/bin/bash

file="states"

for state in $(cat $file)

do

*        echo "Visit beautiful $state"*

done

运行就好了。

for仍然以每次一行的方式遍历的cat命令输出的结果。

 

128     无效的退出参数

2           语法

2.10 双引号及单引号

13.1.5 更改字段分隔符

1.特殊环境变量IFS:内部字段分割符。定义了bash shell用作字段分隔符的一系列字符。

2.默认情况下会将下列字符当做字段分隔符。1)空格 2)制表符 3)换行符

  1. 如果bash shell 在数据中看到了这些字符中的任意一个,它就会假定这表明了列表中一个新数据字段的开始。

在处理包含空格的数据时会比较麻烦。所以需要修改IFS的值。

只识别换行符,就需要这么做:IFS=$’n’。将这个语句假如脚本中,告诉bash shell在数据值中忽略空格和制表符。

#!/bin/bash

file="states"

IFS=$’n’

for state in $(cat $file)

do

*        echo "Visit beautiful $state"*

done

还有一些绝妙用法:假如需要遍历一个文件中用冒号分割的值。就可以IFS=:

如果需要指定多个字符,只需要将它们在赋值行中串起来就行。IFS=$’n’:;”  将换行符、冒号、分号、双引号作为字段分隔符

 

until 命令

until 命令刚好与 while 命令相反。

格式:

until test commands

do 

  other commands

done

until  命令需要制定一条测试命令,这条命令通常产生一个非0的退出状态。只要测试命令的退出状态非0, bash shell就会执行列在循环当中的命令。一旦测试条件返回0退出状态,循环停止。

示例

#!/bin/bash
# using the until command

var1=100

until [ $var1 -eq 0 ]
do
echo $var1
var1=$[ $var1 - 25 ]
done

 

嵌套循环

通常需要迭代存储在文件内部的项。需要结合两种技术:

  • 使用嵌套循环
  • 更改环境变量 IFS

示例

#!/bin/bash
# changing the IFS value
IFSOLD=$IFS
IFS=$'n'
for entry in `cat /etc/passwd | grep ro `
do
echo "Values in $entry -"
IFS=:
for value in $entry
do
echo " $value"
done
done

 

【until循环】

num=1

result=0

until [ $num -ge 3 ]

do

result=$(($result+$num))

num=$((num+1))

done

 

echo $result

 

do

13.9 实例

2     误用 shell 命令

2.2.4        while循环

while [ condition ]

do

statements

done

 

 

该命令的一般形式为: su [选项] [使用者帐号]

13.5嵌套循环

循环语句可以在循环内使用任意类型的命令,包括其他循环命令。

注意在循环嵌套时执行次数是两次循环次数相乘。

 

例子:

*  1 #!/bin/bash*

*  2 var1=3*

*  3 for (( var1=3; var1>0; var1-- ))*

*  4 do*

*  5         echo "for: var1 = $var1"*

*  6         var2=3*

*  7         while [ $var2 -gt 0 ]*

*  8         do*

*  9                 echo "  while: var2 = $var2"*

* 10                 var2=$[ $var2 - 1 ]*

* 11*

* 12                 var3=3*

* 13                 until [ $var3 -eq 0 ]*

* 14                 do*

* 15                         echo "    until: var3 = $var3"*

* 16                         var3=$[ $var3 - 1 ]*

* 17                 done*

* 18         done*

* 19 done*

 

255     规范外的退出状态

【for循环:i的作用域】循环体内部(do/done之间)

for i in $(seq 5)

do

echo $i

done

 

echo $i

--执行

sh test

 

test进行逻辑运算,用[ ]括起来就是test运算

13.9.2 再删除创建的用户

代码如下:

*  1 #!/bin/bash*

*  2 # xcy test, del user*

*  3 IFS=$'n'*

*  4 for user in $(cat /etc/passwd)*

*  5 do*

*  6 #       echo "$user"*

*  7         IFS=:*

*  8         for value in $user*

*  9         do*

* 10                 if [[ $value == xiaochongyong* ]]  #* 这个有点通配符的意思***

* 11                 then*

* 12                         echo "Userid: $value"*

* 13                         userdel $value*

* 14                 fi*

* 15                 break*

* 16         done*

* 17 done*

注意那个break,因为/etc/passwd第一条就是userid,这里读取完userid就退出当前循环。

 

嵌套 if 语句

格式:

if command1

then

  commands

elif  command2

then

  more commands

fi

示例

#!/bin/bash

# looking for a possible value

 

if [ $USER = "rich" ]

then

  echo "Welcome $USER"

  echo "Please enjoy your visit"

elif [ $USER = barbara ]

then

  echo "Special testing account" 

else

  echo "Sorry, you're not allowed here" 

fi

 

 

2.1         变量,数据类型

变量定义:不含保留字(例如“-,*”等),不含空格。

变量的引用:赋值,for循环前不需带$;其他情况引用变量需要带"$"(例如,打印,运算等)。

数据类型:shell变量没有数据类型。

shell语句:=左右不能有空格;shell语句不以”;“结尾。

                                                                                                

do_data

13.7 控制循环

有两个命令可以控制循环内部的情况:

1)break   2)continue

test命令

test命令提供一种检测 if-then 语句中不同条件的方法。如果test命令中的条件评估值为true,test命令以0退出状态代码退出,如果条件为false,则test命令退出。

 

test 命令格式:

  test condition

condition 是一系列 test命令评估的参数和值。

 

在 if-then 语句中使用时,test命令如下所示:

if test condition

then

  commands

fi

 

bash shell 提供一种在 if-then 语句中声明 test 命令的另一种方法:

if [ condition ]

then

   commands

fi

方括号定义在 test 命令中使用的条件。注意,在前半个方括号的后面和后半个方括号的前面必须都有一个空格,否则会得到错误信息。

 

test 命令能够评估以下3类条件:

(1)数值比较:

  • n1 -eq n2:检查 n1 是否等于 n2
  • n1 -ge n2:检查 n1 是否大于或等于 n2
  • n1 -gt n2:检查 n1 是否大于 n2
  • n1 -le n2: 检查 n1 是否小于或等于 n2
  • n1 -lt n2: 检查 n1 是否小于 n2
  • n1 -ne n2:检查 n1 是否不等于 n2

示例

#!/bin/bash

# testing floating point numbers

val1=` echo "scale=4; 10 / 3 " | bc`

echo "The test value is $val1"

if [ $val1 -gt 3 ]

then

   echo "The result is larger than 3"

fi

注意:test 命令无法处理存储在变量 val1 中的浮点值。

(2)字符串比较:

  • str1 = str2:检查 str1 与 str2 是否相同
  • str1 != str2:检查 str1 与 str2 是否不同
  • str1 < str2:检查 str1 是否小于 str2
  • str1 > str2: 检查 str1 是否大于 str2
  • -n str1:检查 str1 的长度是否大于0
  • -z str1:检查 str1 的长度是否为0

字符串相等

示例

#!/bin/bash

# testing string equality

testuser=rich

 

if [ $USER = $testuser ]

then

   echo "Welcom $ testuser"

fi

 

字符串顺序

大于和小于符号一定要转义,否则 shell 会将它们当作重定向符号,将字符串值看作文件名。

大于和小于顺序与在 sort 命令中的顺序不同。

示例

#!/bin/bash

# mis-using string comparisons

 

var1=baseball

var2=hockkey

 

if [ $val1 > $ val2 ]

then

   echo "$val1 is greater than $var2"

else

   echo "$val1 is less than $var2"

fi

 

字符串大小

示例

#!/bin/bash

# testing string length

val1=testing

val2=''

 

if [ -n $val1 ]

then

   echo "The string '$val1' is not empty"

else

   echo "The string '$val1' is empty"

fi

 

if [ -z $val2 ]

then

   echo "The string '$val2' is not empty"

else

   echo "The string '$val2' is empty"

fi

 

if [ -z $val3 ]

then

   echo "The string '$val3' is not empty"

else

   echo "The string '$val3' is empty"

fi

空变量和没有初始化的变量长度为0。

 

(3)文件比较:

  • -d 文件名:  如果文件存在且为目录则为真
  • -e 文件名:   如果文件存在则为真
  • -f 文件名:  如果文件存在且为普通文件则为真
  • -r 文件名: 如果文件存在且可读则为真
  • -s 文件名:  如果文件存在且至少有一个字符则为真
  • -w 文件名:  如果文件存在且可写则为真
  • -x 文件名:  如果文件存在且可执行则为真
  • -o file : 检查 file 是否存在并且被当前用户拥有
  • -G file:检查 file 是否存在并且默认组是否为当前用户组
  • -c 文件名:  如果文件存在且为字符型特殊文件则为真
  • -b 文件名:  如果文件存在且为块特殊文件则为真
  • file1 -ot file2 若 file 旧于 file2,则条件成立

 

示例 

 #!/bin/bash

# check if a file

if [ -e $HOME ]

then 

   echo "The object exists, is it a file?"

   if [ -f $HOME]

   then

     echo "Yes, it's a file!"

   else

     echo "No, it's not a file!"

     if [ -f $HOME/.bash_history]

     then

       echo "But this is a file!"

     fi

  fi

else

   echo "Sorry, the object doesn't exists"

fi

[bash]$ 什意思?

就是个提示符,bash是shell脚本中得一种。linux中,$代码普通用户,#代表root用户。
都是linux基础,学学吧。  

command

13.2 C语言风格的for命令

 

循环结构 

4           Vi编辑器

命名模式:Esc键,“:”英文冒号,“wq”保存退出,“q!”强制退出

插入模式:aAiIuU

删除单词:dw

删除整行:dd

字符串查找:“/”正斜杠

 

continue 忽略本循环中的其他命令,继续下一下循环

13.8 处理循环的输出

直接上例子吧。直接在done后面接 > xxx.txt

 图片 3

 

 

Linux 提供 $? 特殊变量来保存最后一条命令执行结束的退出状态。如果想核对一条命令的退出状态,必须在这条命令运行完成后立即查看或使用变量 $?。一条命令成功完成的退出状态是 0,如果命令执行错误,那么退出状态就会是一个正整数。

【for循环:i的作用域】定义后的程序块

for((i=1;i<=5;i++));do

echo $i

done

                                            

echo $i

--执行

sh test

 

$*  这个程序的所有参数

13.1 for命令

重复执行一系列命令在编程中很常见。

bash shell提供了for命令,允许你创建一个遍历一系列值的循环。每次迭代都使用其中一个值来执行已定义好的一组命令。下面是基本格式

for var in list

do

command

done

在list参数中需要提供迭代中要用到的一系列值。会依次迭代下去。每次迭代中,var会包含列表中要用到的一系列值。

do 和 done直接输入的命令可以是一条或多条标准的bash shell命令。

 

许多程序在脚本命令之间需要某种逻辑流控制,允许脚本根据变量值的条件或者其他命令的结果路过一些命令或者循环执行这些命令。这些命令通常被称为结构化命令。和其他高级程序设计语言一样,shell提供了用来控制程序执行流程的命令,包括条件分支和循环结构,用户可以用这些命令建立非常复杂的程序。与传统的语言不同的是,shell用于指定条件值的不是布尔表达式而是命令和字符串。

【for循环:命令行参数】。

for param

do

echo $param

done

--执行脚本

sh test 123 456 789

【PS】未指定list,将打印所有命令行参数;当没有命令行参数时,什么都不打印

 

2.2 如何执行shell程序

13.4 until命令

和while相反。until命令要求你指定一个通常返回非0退出状态码的测试命令。

只有测试命令退出状态码不为0,bash shell才会执行循环中列出的命令。

一旦返回了退出状态码0,循环就结束了。

格式:

until test commands

do

         other commands

done

 

例子:

*  1 #!/bin/bash*

*  2 # until test*

*  3 var=100*

*  4 until [ $var -lt 0 ]  # 满足条件则结束,不满足则进循环*

*  5 # -eq  ==*

*  6 # -ge >=*

*  7 # -lt <*

*  8 do*

*  9         echo "until test: var = $var"*

* 10         var=$[ $var - 25 ]*

* 11 done*

也可以执行多个测试命令,只在最后一个成立时停止。

 

for命令

for 命令用于通过一系列值重复的循环。每次重复使用系列中的一个值执行一个定义的命令集。

格式:

for var in list

do

  commands

done

在参数 list 中提供一系列用于迭代的值。for 循环认为每个值都用空格分隔。

 

注意:可以将 do 语句与 for 语句放在同一行,但是必须使用分号将它与列表项分开:

  for var in list; do

 

列表值中包含单引号的处理方法

  • 使用转义字符(反斜杠符号)来转义单引号
  • 使用双引号来定义使用单引号的值

 

内部字段分隔符(internal field separator, IFS)定义了 bash shell 用作字段分隔符的字符列表。默认情况下,bash shell 将下面的字符看作字段分隔符。

  • 空格
  • 制表符
  • 换行符

如果处理能够包含空格的数据时,就会产生干扰,可以在 shell 脚本中暂时更改环境变量 IFS 的值,限制 bash shell 看作是字段分隔符的字符。

示例

#!/bin/bash
# reading values from a file

file="states"

IFS=$'n'
for state in `cat $file`
do
  echo "Visit beautiful $state"
done

 

使用通配符读取目录或处理多目录

示例

#!/bin/bash
# iterate through all the files in a directory

for file in /home/txj/* /home/txj/.b*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done

 

bash基础,gitbash

 

echo $STR

13.3 while命令

某种意义是if-then和for循环的混杂体。

while命令允许定义一个要测试的命令,然后循环执行一组命令,只要定义的测试命令返回的退出状态码0.它会在每次迭代的一开始测试test命令。在test命令返回非0退出状态码时,while会停止执行那组命令。(**test返回0**,就接着迭代,否则暂停)

select

格式

select variable in list

do

    commands

done

类别参数是用空格隔开的构建菜单的文本项列表。select 命令将列表中的每一项显示为一个编号选项,然后为选择显示一个特殊的提示符(由 PS3 环境变量定义)。

示例

#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"

do
  break
done
echo "You have selected $var"

下面是该脚本运行的结果: 

What is your favourite OS? 

1) Linux 

2) Gnu Hurd 

3) Free BSD 

4) Other 

#? 1 

You have selected Linux

2.1.1        整数运算(+-*/%):let,expr

1)let:双引号

例如,let "x=$x+1"

2)expr:`,空格,特殊字符前需要使用转义符号

例如,x=`expr $x + 4`,x=`expr $x * 4`

【PS】不能进行浮点数运算,没有浮点数数据类型。

【例子:算术运算,字符拼接,shell的无数据类型】

#!/bin/bash

x=2007

let "x=$x+1"

echo $x

 

x=`expr $x + 4`

echo $x

echo $(expr $x / 2)

x='Olmpic'$x

echo x=$x

 

y=12

y=`expr $y * 2`

echo $y

 

1.4. mkdir和rmdir

13.2.2 使用多个变量

C语言风格的for命令允许为迭代使用多个变量。循环会单独处理每个变量,可以为每个变量定义不同的迭代过程。

尽管可以使用多个变量,但你只能在for循环中定义一种条件。

例子:

*  1 #!/bin/bash*

*  2 # C for multiple variables test*

*  3 for (( i=10, b = 0; i > 0; i--, b++ ))*

*  4 do*

*  5         echo "For Test: i = $i, b = $b"*

*  6 done*

 

if-then 高级特征

双圆括号

((  expression ))

表示数学表达数,允许在比较中包含高级数学公式。除了 test 命令使用的标准数学操作符,还包括:

 符号       描述

val++   后增量

val--    后减量

++val   前增量

--val    前减量

!     逻辑否定

~      逐位取反

**     取幂

<<      左移

>>      右移

&           

|

&&      逻辑与

||        逻辑或

 

示例

if (( $val1 ** 2 > 90 ))

then

   (( val2 = $val1 ** 2 ))

   echo "The square of $val1 is $val2"

fi

 

双方括号

[[ expression ]]

双括号命令提供了模式匹配。

示例

if [[ $USER == r* ]]

then

  echo "Hello $USER"

else

  echo "Sorry, I don't know you"

fi

 

2.2         流程控制

例如:if [ `expr $a % 3` -ne 0 ],while [ "$var" != "end" ],尽量分开写,这样也挺好看也便于识别。

 

Linux退出状态代码

【hello world】脚本的执行:hello

#!/bin/bash

#变量的使用

str='hello world'

echo $str

echo str

 

--执行文件

bash hello

sh hello

chmod u+x hello

hello

 

if [ variable = value ]

13.1.1 读取列表中的值

每次for命令遍历值列表,它都会将列表中的下一个值赋给$var变量。最后一次迭代后,$var变量的值会在shell脚本中剩余部分一直保持有效。(除非你修改了它)

 

C式 for 循环

格式

for (( variable assignment ;  condition ;  iteration process ))

有几项不遵循标准 bash shell 的 for 方法

  • 变量的赋值可以包含空格
  • 条件中的变量不以美元符号做前缘
  • 迭代处理式不使用 expr 命令格式

示例

#!/bin/bash
# multiple variables

for (( a=1, b=10; a<=10; a++,b-- ))
do
echo "$a - $b"
done

 

 

2.2.1        if条件控制

if [ expression ] ;then statements

fi

 

if [ expression ] ;then statements

else   statements

fi

 

if [ expression ] ;then statements

else if  [ expression ] then statements

else  statements

fi

 

if [ expression ] ;then statements

elif  [ expression ] ;then statements

else  statements

fi

【PS】

若then换行,则then前无需加;。

[和]的后、前有空格。

 

let sum=sum+$x  //shell中算术计算使用let

13.1.6 用通配符读取目录

可以用for命令来自动遍历目录中的文件。进行此操作时,必须在文件名或路径名中使用通配符。

它会强制使用文件扩展匹配(生成匹配指定通配符的文件名或路径名的过程)。

比如下面的例子:

*  1 #!/bin/bash*

*  2 for file in /home/xcy/shell/**

*  3 do*

*  4         if [ -d "$file" ]  #加双引号为了解决文件名含有空格的问题*

*  5         then*

*  6                 echo "$file is directory"*

*  7         elif [ -f "$file" ] #如果文件名有空格,没有双引号就会出错*

*  8         then*

*  9                 echo "$file is file"*

* 10         fi*

* 11 done*

for语句首先使用了文件扩展匹配来遍历通配符生成的文件列表,然后会遍历列表中的下一个文件。可以将任意多的通配符放进列表中。

 

 

2.1.2        赋值

x=200

let "x=$x+1"

x=’hello’$x

y=$(expr $x / 2)

y=`expr $y * 2`

 

result=$(($result+$num))

num=$((num+1))

 

shell编程中它们是没有类型的,简称弱类型编程语言,在这个变量中可以保含一个数字,一个字符串,一个单词等。你并不需要声明这个变量,它会在引用这个变量时创建它。

13.6循环处理文件数据

通常需要遍历存储在文件中的数据,需要结合两种技术:

1)使用嵌套循环

2)修改IFS环境变量

 

例子:

*  1 #!/bin/bash*

*  2 # changing the IFS value*

*  3 IFS.OLD=$IFS*

*  4 IFS=$'n'  # 分隔符变为换行符*

*  5 for entry in $(cat /etc/passwd)*

*  6 do*

*  7         echo "Values in [$entry]"*

*  8         IFS=:   # 分隔符变为冒号*

*  9         for value in $entry*

* 10         do*

* 11                 echo "   $value"*

* 12         done*

* 13 done*

 

外循环解析一行一行的用户信息。内循环通过冒号分割,解析一个用户的具体信息。

 

 

【for循环:无in [list]】

for var ;do

 echo ok

done

--执行

sh test

sh test 1  "hello world" a

 

command

13.9.2 创建多个用户账户

让系统管理员更轻松。用脚本创建用户

1.先建立一个文本,里面放用户id和name。用逗号分隔

图片 4

  1. 再去读取上述文件中的信息

while IFS=',' read -r userid name

这个还是蛮有技巧的。read会自动读取读取.csv文本文件的下一行内容,不需要再写一个循环来处理。

read返回false时(就是读取完了)while就会退出,妙哉。

代码如下:

*  1 #!/bin/bash*

*  2 # shell add user account*

*  3 input="users.csv"*

*  4 while IFS=',' read -r userid name #读取里面的数据,IFS要设为逗号*

*  5 do*

*  6         echo "adding id:$userid  name:$name"*

*  7         useradd -c "$name" -m $userid*

*  8 done < "$input"*

 执行需要sudo权限。

126     命令无法执行

2.2.2        case分支结构

case "$var" in

cindition1 ) statements;;

cindition2 ) statements;;

...

* ) statements;;

esac

 

 

 

其中operator为+ - * / %, 但对*的使用要用转义符/,如:

13.1.2 读取列表中的复杂值

列表值的单引号是个大麻烦。

有两个方法可以解决

1)使用转义字符。将单引号转义

2)使用双引号来定义用到单引号的值

在某个值两边使用双引号时,shell并不会将双引号当成值的一部分

 

if-then-else

格式:

if command

then

    commands

else

    commands

fi

示例 

#!/bin/bash
#testing multiple commands in the then section
testuser=rich
if grep $testuser /etc/passwd
then
  echo The bash files for user $testuser are:
  ls -a /home/$testuser/.b*
else
  echo "The user name $testuser doesn't exist on this system"
fi

 

2.1.3        比较操作      

1)-eq,-ne,-gt和-ge,-lt和-le,-z(为空),-n(非空)

2)=,!=,>(无>=),<(无<=)

【PS】

字符串比较时,尽量不用-z,而用!-n代替。

能用1)尽量不用2)。

 

Linux Shell 基本语法 

本章讨论bash shell的循环命令for、while和until

分支条件

【break/continue】

for i in `seq 1 5`;do

if [ $i = 3 ];the

continue

else echo $i

fi

done

 

 

2.15.1 For循环

13.2.1 C语言的for命令

以下是bash中C语言风格的for循环的基本格式:

for (( variable assignment ; condition ; interation process ))

例子:

for (( a = 1; a < 10; a++ ))

(1)变量赋值可以有空格

(2)条件中的变量不以美元符开头

(3)迭代过程的算式没有用expr命令格式。

 

例子:

*  1 #!/bin/bash*

*  2 # C for test*

*  3 for (( i = 10; i > 0; i-- ))*

*  4 do*

*  5         echo "For Test: i = $i"*

*  6 done*

 

while 命令

while 命令格式

while test command

do

  other commands

done

在 while 命令中定义的 test 命令与在 if-then 语句中定义的格式一样。while 关键是指定的 test 命令的退出状态必须根据循环中命令的运行情况改变。

示例

#!/bin/bash
# while command test

var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done

 

如果有多条 test 命令,只有最后一条测试命令的退出状态是用来决定循环是何时停止的。

#!/bin/bash
# tesing a multicommand while loop

var1=10

while echo $var1
        [ $var1 -ge 0 ]
do
echo "This is inside the loop"
var1=$[ $var1 - 1 ]
done

  

【for循环:seq】

for i in `seq 1 5`;do

echo TEST!

done

 

setup ()

 

3           bash脚本例子

1.1.  cp命令

1     通常的未知错误

【case分支】

var=12

case "$var" in

[a-z] ) echo 'lowercase letter!';;

[0-9] ) echo 'number';;

* ) echo other character!;;

esac

 

For循环示例

 

【if条件:带参脚本】

#!/bin/bash

if [ $1 = 10 ];then echo right!

else echo wrong!

fi

--执行

sh test 123

【PS】$1用于匹配命令行的第1个参数。(bash中的保留字)

 

pattern2)

代码      描述

2.2.6        break/continue

 

echo $sq

128+x   Linux 信号 x 的致使错误

【局部变量:局部变量的作用域(函数体内)】

#!/bin/bash

function test {

local var=world

echo $var

}

 

var=hello

 

echo $var

test

echo $var

【PS】局部变量:首次被赋值时,变量前面加上local。

 

同传统的编程语言一样,shell提供了很多特性,这些特性可以使你的shell script编程更为有用,如:数据变量、参数传递、判断、流程控制、数据输入和输出,子程序及以中断处理等。

0     命令成功完成

2.1.4        按位操作

&,|

【位运算:】

[email protected]:~/zzhTest> echo $(expr 1 & 0)

0

[email protected]:~/zzhTest> echo $(expr 1 | 0)

1

#!/bibn/bash

if [ $str !-n ];then

echo null!!

fi

 

sq=`expr $int /* $int`

continue 命令

continue 命令是一种提前停止循环内命令,而不完全终止循环的方法。

示例

#!/bin/bash
# continuing an outer loop

for (( a=1; a<=5; a++ ))
do
echo "Iteration $a:"
for (( b=1; b<3; b++ ))
do
if [ $a -gt 2 ] && [ $a -lt 4 ]
then
continue 2
fi
var3=$[ $a * $b ]
echo " The result of $a * $b is $var3"
done
done

 

1           概念

bash(sh,pdsh扩充): GNU Bourne-Again Shell

 

sh:Bourne Shell,编程优秀,用户交互不便。         

csh:C Shell,编程接口不如sh,用户界面友好,与C语言语法相似。      ——>tcsh

ksh:Korn Shell,集成了sh和csh的优点,并完全兼容sh。               ——>pdsh(Public Domain Korn Shell)

zsh

 

echo "enter a number"

 

5           相关拓展

保留字

正则

函数

输入,输出: >,>>,>2,>1,>&

For循环

变量的作用:整数,字符串,计数,文件属性

 

 

次元立方

 

sum=0

 


repeat语句
repeat语句是tcsh提供的独有的循环语句.使用repeat命令要求shell对一个命令执行一定的次数.
语法格式:
  repeat count command
如;

foreach num ( $ *)
repeat $num echo -n " *"
echo " "
end

 

3.1. 基础

复合条件检查 

  [ condition1 ] && [ condition2 ]

两个条件必须都满足才能执行 then 部分

  [ condition1 ] || [ condition2 ] 

如果任意一个条件评估为 true,那么就会执行 then 部分

示例

#!/bin/sh 
mailfolder=/var/spool/mail/james 
[ -r "$mailfolder" ]||{ echo "Can not read $mailfolder" ; exit 1; } 
echo "$mailfolder has mail from:" 
grep "^From " $mailfolder

该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令: 

  -打印错误信息 

  -退出程序 

我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。 不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。

 

 

for $int in 1 2 3 4 5

循环的输出

可以通过在 done 命令的末尾添加管道或重定向循环的输出结果。

示例

#!/bin/bash
# redirecting the for output to a file

for (( a=1; a<10; a++ ))
do
echo "The number is $a"
done > test10-23.txt

[ -n "$var" ] :判断$var变量是否有值

127     没有找到命令

command; #分号

expr 5 /* 5

While循环的示例

done

$? 上一个指令的返回值

1.10. grep命令

;;                                //注意符号是两个 ;

搜寻输出的特定文字

fi

1.7. su命令

...

int=`expr $int + 1`

break 立即退出循环

command

3.3. 在使用if、while时,在注意变量与符号之间的分割

....

int1 -ne int2 不等?

语法:ls [选项] [目录或是文件]

Shell编程中的注释以#开头

2.8 数字运算

本文由美高梅赌堵59599发布于首页,转载请注明出处:Linux Shell 基本语法 ,编程接口不如sh

关键词: