Linux shell脚本

solitary@ubuntu:myshell$ wc < temp_date.txt 
 2 11 73
solitary@ubuntu:myshell$ wc << EOF
> test string 1
> test string 2
> test string 3
> EOF
 3  9 42

   371    setterm --help    
   373    man -k terminal
   374    info terminal
   376    ls -l
   377    ls -f
   383    cd Documents/
   384    ls -a
   385    cat bashrc.txt
   386    ls -f -r
   390    ls -li
   395    sudo apt-get install tree
   396    tree  /home
   399    more Makefile
   400    less Makefile
   401    man less
   402    less Makefile
   403    tail -n 2 Makefile
   404    tail -f
   405    tail -f Makefile
   406    cat -n Makefile
   407    cat -f Makefile
   408    cat -T Makefile
   409    cat -b Makefile
   410    ps
   411    ls -li
   412    cat -b Makefile
   413    ls -f -r
   414    ls -a
   417    ps
   418    ps -ef
   419    top
   420    tree ps
   421    top
   422    kill 1569
   423    eixt
   424    exit
   425    ps -f
   426    exit
   427    ps --forest
   428    pwd
   430    pwd ; ls
   434    ps -f
   436    (pwd;ls)
   438    pwd; ls
   444    kill 3850
   445    ps -f
   451    kill -s HUB 3850
   452    ps
   453    exit
   454    mount
   455    df     通过df命令很容易发现哪个磁盘的存储空间快没了
   456    fd -h
   457    df -h
   458    du    du命令可以显示某个特定目录(默认情况下是当前目录)的磁盘使用情况

   459    du -chs
   460    du -c
   461    du -h
   462    du -s
   463    cat /etc/passwd
   464    ls -lf /bin/bash
   465    ls -l /bin/bash
   466    ls -l /bin/sh
   467    /bin/bash
   468    /bin/dash
   469    ps -f
   470    /bin/dash
   471    ps -f
   472    bash
   473    ps -f
   474    dash
   475    ps -forest
   476    ps --forest
   477    bash
   479    exit
   481    kill 3959
   482    pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls ; echo $BASH_SUBSHELL
   483    $ (pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls ; echo $BASH_SUBSHELL)
   484    ( pwd ; (echo $BASH_SUBSHELL))
   486    sleep 11
   487    sleep 11&
   488    ps -f
   490    sleep 11&
   491    jobs -l
   494    jobs
   495    coproc sleep 10
   496    coproc my_job { sleep 10; }
   497    type ps
   498    which ps
   499    type cd
   501    cd .
   503    pwd
   505    /bin/pwd
   507    history
   518    history -a
   519    cat -b .bash_history
   520    cat .bash_history

   521   alias li="ls -li"
   522    li
   523    echo $my_variable
   525    my_variable=hell
   527    ps -f
   529    export my_variable
   530    echo $my_variable
   531    exit
   535    set
   537    printenv
   538    env

 设置 PATH 环境变量

只需引用原来的PATH值,然后再给这个字符串添加新目录就行了,,如果希望子shell也能找到你的程序的位置,一定要记得把修改后的PATH环境变量用 export 导出,   由父shell设置但并未导出的变量都是局部变量 ,子shell无法继承局部变量

 $ echo $PATH 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin: 
 /sbin:/bin:/usr/games:/usr/local/games 
 $ 
 $ PATH=$PATH:/home/christine/Scripts 
 $ 
 $ echo $PATH 
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/ 
  games:/usr/local/games:/home/christine/Scripts 
 $ PATH=$PATH:.     #### 程序员通常的办法是将单点符也加入PATH环境变量。该单点符代表当前目录
$ mytest=(one two three four five)
$ echo $mytest 
one
$
$ echo ${mytest[2]}
three 
$
$ echo ${mytest[*]} 
one two three four five 
$
$ mytest[2]=seven
$ 
$ echo ${mytest[*]}
one two seven four five 

 $ unset mytest[2]
 $ 
 $ echo ${mytest[*]}
 one two four five 
 $ 
 $ echo ${mytest[2]}

 $ echo ${mytest[3]}
 four

$unset mytest
$ 
$ echo ${mytest[*]}

solitary@ubuntu:~$ finger solitary
Login: solitary       			Name: Ubuntu1804
Directory: /home/solitary           	Shell: /bin/bash
On since Sun Aug  9 22:24 (PDT) on :1 from :1 (messages off)
No mail.
No Plan.
solitary@ubuntu:~$ chfn solitary
Password: 
Changing the user information for solitary
Enter the new value, or press ENTER for the default
	Full Name: Ubuntu1804
	Room Number []: 1804 
	Work Phone []: 15030520917
	Home Phone []: 110
solitary@ubuntu:~$ finger solitary
Login: solitary       			Name: Ubuntu1804
Directory: /home/solitary           	Shell: /bin/bash
Office: 1804, +1-503-052-0917		Home Phone: 110
On since Sun Aug  9 22:24 (PDT) on :1 from :1 (messages off)
No mail.
No Plan.
solitary@ubuntu:~$ 
solitary@ubuntu:~$ grep solitary /etc/passwd
solitary:x:1000:1000:Ubuntu1804,1804,15030520917,110:/home/solitary:/bin/bash
solitary@ubuntu:~$ 
solitary@ubuntu:~$ sudo chage test -E 2020-8-12
solitary@ubuntu:~$ sudo chage test -I 999999


 建立名为shared的共享文件夹

$ groupadd shared                  #建立一个共享组
$ usermod -G shared solitary       #把solitary用户加入到shared组中
$ mkdir shareDir                   #创建一个待共享的文件夹
$ chgrp shared shareDir            #改变共享文件夹的属组为shared
$ chmod g+s sharedDir              #设置shareDir文件夹的数组属性,把SGUID位置位,以保证
                                   #目录中新建文件都用shared作为默认属组
$ umask 002                        #使在共享文件夹下创建的文件对属组的其他用户是可写的
#####验证
$ cd ./shareDir
$ touch demo.txt
$ ls -l
-rw-rw-r-- 1 solitary shared 0 Aug 11 13:19 demo.txt
  •  管道被放在命令之间,将一个命令的输出重定向到另一个命令中:
  •   command1 | command2   
  • Linux系统实际上会同时运行这两个命令,在
  • 系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据
  • 传输不会用到任何中间文件或缓冲区

管道连接

solitary@ubuntu:myshell$ ls -al | sort
drwxr-xr-x 24 solitary solitary  4096 Aug 12 09:12 ..
drwxr-xr-x  2 solitary solitary  4096 Aug 12 09:19 .
-rw-r--r--  1 solitary solitary     0 Aug 12 09:13 rpm.list
-rw-r--r--  1 solitary solitary 13623 Aug 11 16:50 log.200811
-rw-r--r--  1 solitary solitary   366 Aug 12 09:19 da
-rw-r--r--  1 solitary solitary    73 Aug 12 09:04 temp_date.txt
-rwxr--r--  1 solitary solitary   755 Aug 11 16:49 my_shell.sh
total 36
#!/bin/bash 
# An example of using the expr command 
var1=10 
var2=20 
var3=$(expr $var2 / $var1) 
echo The result is $var3
var1=100 
var2=50 
var3=45 
var4=$[$var1 * ($var2 - $var3)] 
echo The final result is $var4

 

$ bc -q 
var1=10 
var1 * 4 
40 
var2 = var1 / 5 
print var2 
2 
quit 
$
#scale变量的默认值是0。在scale值被设置前,bash计算器的计算结果不包含小数位。在将
#其值设置成4后
 $ bc -q 
 3.44 / 5 
 0 
 scale=4 
 3.44 / 5 
 .6880 
 quit 
 $

shell script
$ cat test10 
#!/bin/bash 
var1=100 
var2=45 
var3=$(echo "scale=4; $var1 / $var2" | bc) 
echo The answer for this is $var3 
$

重定向+bc

   在bash 计算器中创建的变量只在bash计算器中有效,不能在shell脚本中使用

 #!/bin/bash 
 var1=10.46 
 var2=43.67 
 var3=33.2 
 var4=71 
 var5=$(bc << EOF 
 scale = 4 
 a1 = ( $var1 * $var2) 
 b1 = ($var3 * $var4) 
 a1 + b1 
 EOF 
 ) 
 echo The final answer for this mess is $var5 
 $
#!/bin/bash 
# Testing nested ifs - use elif & else 
# 
testuser=NoSuchUser 
# 
if grep $testuser /etc/passwd 
then 
 echo "The user $testuser exists on this system." 
# 
elif ls -d /home/$testuser 
then 
 echo "The user $testuser does not exist on this system." 
 echo "However, $testuser has a directory." 
# 
else 
 echo "The user $testuser does not exist on this system." 
 echo "And, $testuser does not have a directory." 
fi

##template
if command1
 then 
  command set 1 
 elif command2
 then 
  command set 2 
 elif command3
 then 
  command set 3 
 elif command4
 then 
  command set 4 
 fi
#!/bin/bash 
# Using numeric test evaluations 
#
value1=10 
value2=11 
# 
if [ $value1 -gt 5 ] 
then 
 echo "The test value $value1 is greater than 5" 
fi 
# 
if [ $value1 -eq $value2 ] 
then 
 echo "The values are equal" 
else 
 echo "The values are different" 
fi 
# 
$

 

#!/bin/bash 
score=80
if [ $score -ge 90 ]
then
        echo "Great!"
elif [ $score -ge 80 ] && [ $score -lt 90 ]
then
        echo "Good"
elif [ $score -ge 60 ] && [ $score -lt 80 ]
then
        echo "pass"
else
        echo "No pass"
fi

 

#!/bin/bash
file1="my_shell.sh"
file2="shell2.sh"
path="$HOME/myshell"
if [ -x $path/$file1 ] && [ -x $path/$file2 ]
then
        if [ $file1 -nt $file2 ]
        then
                echo "$file1 is newer then $file2"
        else
                echo "$file1 is older then $file2"
        fi
else
        echo "The two files at less have one is not exist"
fi

   
#!/bin/bash
val1=10
if (( $val1 ** 2 > 90 ))
then
        (( val2=$val1 ** 2 ))
        echo "The square of $val1 is $val2"
fi

 

#!/bin/bash
mathscore=80
case $mathscore in
80 | 90)
        echo "great" ;;
70 | 60)
        echo "good" ;;
*)
        echo "not pass"a ;;
esac
#!/bin/bash 
 # an example of how to properly define values 
 for test in Nevada "New Hampshire" "New Mexico" "New York" 
 do 
  echo "Now going to $test" 
 done 
 $ ./test3 
 Now going to Nevada 
 Now going to New Hampshire 
 Now going to New Mexico 
 Now going to New York 
 $

IFS=$'\n';:"     -------> 这个赋值会将换行符、冒号、分号和双引号作为字段分隔符

#!/bin/bash
path="$HOME/*"
for file in $path 
do 
 if [ -d "$file" ] 
 then 
 echo "$file is a directory" 
 elif [ -f "$file" ] 
 then 
 echo "$file is a file" 
 fi 
done
#!/bin/bash 
# testing the C-style for loop 
for (( i=1; i <= 10; i++ )) 
do 
 echo "The next number is $i" 
done

#!/bin/bash 
# multiple variables 
for (( a=1, b=10; a <= 10; a++, b-- )) 
do 
 echo "$a - $b" 
done
#!/bin/bash
var=10
while [ $var \> 0 ]       #或者写成  while [ $var -gt 0 ]
do
        echo $var
        var=$[ $var - 1]
done
echo
#!/bin/bash
#until  test
var=100
until [ $var -eq 0 ]
do
        echo $var
        var=$[ $var - 25 ]
done
echo
#!/bin/bash
sum=0
for (( i=0; i<10; ++i ))
do
        for ((j=0; j<10; ++j))
        do
                sum=$[$sum + $j]
        done
        echo $sum
done
echo
#!/bin/bash
IFS.OLD=$IFS
IFS=$'\n'
for entry in $(cat /etc/passwd)
do
        echo "Values in $entry -"
        IFS=:
        for value in $entry
        do
                echo "   $value"
        done
done
IFS=$IFS.OLD
echo

 

#!/bin/bash 
#找到PATH路径下的所有可执行文件
# finding files in the PATH 
IFS=: 
for folder in $PATH 
do 
 echo "$folder:" 
 for file in $folder/* 
 do 
 if [ -x $file ] 
 then 
 echo " $file" 
 fi 
 done 
done 
$
$ cat test26 
 #!/bin/bash 
 # process new user accounts 
 input="users.csv" 
 while IFS=',' read -r userid name 
 do 
  echo "adding $userid" 
  useradd -c "$name" -m $userid 
 done < "$input" 
 $
  •  从终端命令行输入的数据,从可执行的文件作为第1个参数,bash里用" $0 " 引用,第二个参数用 " $1 "引用,以此类推,直到引用到  "  $9 ",也就是除了可执行文件名的额外第9个参数后,再想要更多引用时,比如引用第10个参数,需要遵循 " ${10}  "的格式,也就是需要在数字两边额外加上花括号!
#!/bin/bash
#计算命令行输入的数据的阶乘
sum=1
for (( i=1; i <= $1; ++i))
do
        sum=$[ $sum * $i ]
done
echo "$1! = $sum"
echo

##运行演示
solitary@ubuntu:myshell$ ./shell2.sh 5
5! = 120

 

 #!/bin/bash 
 # Using basename with the $0 parameter 
 # basename命令会返回不包含路径的脚本名。
 name=$(basename $0) 
 echo 
 echo The script name is: $name
  •  特殊变量$#含有脚本运行时携带的命令行参数的个数
  • $*变量会将命令行上提供的所有参数当作一个单词保存
  • $@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词,你就能够遍历所有的参数值,,得到每个参数。这通常通过for命令完成
#!/bin/bash 
# Grabbing the last parameter 
# 
params=$# 
echo 
echo The last parameter is $params 
echo The last parameter is ${!#} 
echo

$ bash test10.sh 1 2 3 4 5
The last parameter is 5 
The last parameter is 5
#!/bin/bash 
# testing $* and $@ 
# 
echo 
echo "Using the \$* method: $*" 
echo 
echo "Using the \$@ method: $@" 
$

$ ./test11.sh rich barbara katie jessica
Using the $* method: rich barbara katie jessica 
Using the $@ method: rich barbara katie jessica 
$

 

#!/bin/bash
# testing $* and $@ 
#
echo 
count=1 
# 
for param in "$*" 
do 
 echo "\$* Parameter #$count = $param" 
 count=$[ $count + 1 ] 
done 
# 
echo 
count=1 
# 
for param in "$@" 
do 
 echo "\$@ Parameter #$count = $param" 
 count=$[ $count + 1 ] 
done 
$ 
$ ./test12.sh rich barbara katie jessica
$* Parameter #1 = rich barbara katie jessica 
$@ Parameter #1 = rich 
$@ Parameter #2 = barbara 
$@ Parameter #3 = katie 
$@ Parameter #4 = jessica 
$

shift,默认情况下它会将每个参数变量向左移动一个位置,变量$3的值会移到$2中,变量$2的值会移到$1中,而变量$1的值则会被删除(注意,变量$0的值,也就是程序名,不会改变

#!/bin/bash 
# demonstrating the shift command
echo 
count=1 
while [ -n "$1" ] 
do 
 echo "Parameter #$count = $1" 
 count=$[ $count + 1 ] 
 shift 
done 
$ 
$ ./test13.sh rich barbara katie jessica
Parameter #1 = rich 
Parameter #2 = barbara 
Parameter #3 = katie 
Parameter #4 = jessica 
$

 通过使用shift命令的参数,就可以轻松地跳过不需要的参数

#!/bin/bash 
# demonstrating a multi-position shift 
# 
echo 
echo "The original parameters: $*" 
shift 2 
echo "Here's the new first parameter: $1" 
$ 
$ ./test14.sh 1 2 3 4 5
The original parameters: 1 2 3 4 5 
Here's the new first parameter: 3
#!/bin/bash 
# extracting command line options and values 
echo 
while [ -n "$1" ] 
do 
 case "$1" in 
 -a) echo "Found the -a option";; 
 -b) param="$2" 
 echo "Found the -b option, with parameter value $param" 
 shift ;; 
 -c) echo "Found the -c option";; 
 --) shift 
 break ;; 
 *) echo "$1 is not an option";; 
 esac 
 shift 
done 
# 
count=1 
for param in "$@" 
do 
 echo "Parameter #$count: $param" 
 count=$[ $count + 1 ] 
done 
$ 
$ ./test17.sh -a -b test1 -d
Found the -a option 
Found the -b option, with parameter value test1 
-d is not an option 
$
  • getopt 格式化命令参数 结合set使用, getopt命令并不擅长处理带空格和引号的参数值。它会将空格当作参数分隔符而不是根据双引号将二者当作一个参数
  • set命令的选项之一是双破折线(--),它会将命令行参数替换成set命令的命令行值,getopt格式化后的命令行参数来替换原始的命令行参数
  • getopts命令(注意是复数)内建于bash shell .   getopts optstring variable  ,getopts命令将当前参数保存在命令行中定义的variable中.
  • getopts命令会用到两个环境变量。如果选项需要跟一个参数值,OPTARG环境变量就会保存这个值,OPTIND环境变量保存了参数列表中getopts正在处理的参数位置
solitary@ubuntu:myshell$ getopt ab:cd -a -b test1 -cd test2 test3
 -a -b test1 -c -d -- test2 test3

 

#!/bin/bash 
# Extract command line options & values with getopt 
# 
set -- $(getopt -q ab:cd "$@") 
# 
echo 
while [ -n "$1" ] 
do 
 case "$1" in 
 -a) echo "Found the -a option" ;; 
 -b) param="$2" 
 echo "Found the -b option, with parameter value $param" 
 shift ;; 
 -c) echo "Found the -c option" ;; 
 --) shift 
 break ;; 
 *) echo "$1 is not an option";; 
 esac
shift 
done 
# 
count=1 
for param in "$@" 
do 
 echo "Parameter #$count: $param" 
 count=$[ $count + 1 ] 
done 
# 
$

#运行演示
$ ./test18.sh -ac
Found the -a option 
Found the -c option 
$
$ ./test18.sh -a -b test1 -cd test2 test3 test4
Found the -a option 
Found the -b option, with parameter value 'test1' 
Found the -c option 
Parameter #1: 'test2' 
Parameter #2: 'test3' 
Parameter #3: 'test4' 
$
  • #!/bin/bash 
    # simple demonstration of the getopts command 
    # 
    echo 
    while getopts :ab:c opt 
    do 
     case "$opt" in 
     a) echo "Found the -a option" ;; 
     b) echo "Found the -b option, with value $OPTARG";; 
     c) echo "Found the -c option" ;; 
     *) echo "Unknown option: $opt";; 
     esac 
    done 
    $ 
    $ ./test19.sh -ab test1 -c
    Found the -a option 
    Found the -b option, with value test1 
    Found the -c option 
    $
    $ ./test19.sh -b "test1 test2" -a
    Found the -b option, with value test1 test2 
    Found the -a option 
    $
  • wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== 在getopts处理每个选项时,它会将OPTIND环境变量值增一。在getopts完成处理时,你可以使用shift命令和OPTIND值来移动参数
#!/bin/bash 
# Processing options & parameters with getopts 
# 
echo 
while getopts :ab:cd opt 
do 
 case "$opt" in 
 a) echo "Found the -a option" ;; 
 b) echo "Found the -b option, with value $OPTARG" ;; 
 c) echo "Found the -c option" ;; 
 d) echo "Found the -d option" ;; 
 *) echo "Unknown option: $opt" ;; 
 esac 
done 
# 
shift $[ $OPTIND - 1 ]     #移除所有已经处理过的参数
# 
echo 
count=1 
for param in "$@" 
do 
 echo "Parameter $count: $param" 
 count=$[ $count + 1 ] 
done

# 运行演示
$ 
$ ./test20.sh -a -b test1 -d test2 test3 test4
Found the -a option 
Found the -b option, with value test1 
Found the -d option 
Parameter 1: test2 
Parameter 2: test3 
Parameter 3: test4 
$
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

REPLY环境变量会保存输入的所有数据,可以在shell脚本中像其他变量一样使用

#!/bin/bash 
# timing the data entry 
# 
if read -t 5 -p "Please enter your name: " name     # -t 5 设置了输入5秒的超时检测
then 
 echo "Hello $name, welcome to my script" 
else 
 echo 
 echo "Sorry, too slow! " 
fi 
$ 
$ ./test25.sh
Please enter your name: Rich
Hello Rich, welcome to my script 
$
#!/bin/bash 
# getting just one character of input 
# 
read -n1 -p "Do you want to continue [Y/N]? " answer 
case $answer in 
Y | y) echo 
 echo "fine, continue on…";; 
N | n) echo 
 echo OK, goodbye 
 exit;; 
esac 
read -s -p "Enter your password: " pass
echo "This is the end of the script" 
$ 
$ ./test26.sh
Do you want to continue [Y/N]? Y
fine, continue on…

 从文件中读取数据

#!/bin/bash
count=1
cat testFile | while read line
do
        echo "Line $count: $line"
        count=$[ $count +1 ]
done
echo "Finished processing the file"

#运行检测
Line 1: I'm so trouble with the thing
Line 2: that there have a company want to job me with
Line 3: ten thousands and two hundred
Finished processing the file

 

你可能感兴趣的:(shell,linux,bash)