shell腳本編寫-1

1、腳本調試-腳本運行前要進行腳本調試

   bash -n /path/to/some_script 檢測腳本中的語法錯誤

   bash -x /path/to/some_script 調試執行

2、shell是弱類型編程語言

1)、無須指定變量類型,默認為字符型;變量參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用

如:bash 不支持浮點數

  2)變量命名法則

不能使程序中的保留字:例如if, for

只能使用數字、字母及下劃線,且不能以數字開頭

見名知義

統一命名規則,例如駝峰命名法

3、本地變量

生效范圍為當前shell進程,對當前shell 之外的其它shell 進程,包括當前shell 的子shell 進程均無效;

1)、變量賦值:name=‘value’

可以使用引用value:

(1) 可以是直接字串; name=“root"

(2) 變量引用:name="$USER"

(3) 命令引用:name=` COMMAND `, name =$(COMMAND)

"" :弱引用,其中的變量引用會被替換為變量值

'' :強引用,其中的變量引用不會被替換為變量值,而保持原字符串

2)、變量引用即是引用或者使用變量的值,格式為:${name}, $name;前一種格式較為穩妥

3)、顯示已定義的所有變量:set

     刪除變量:unset name

4、環境變量:生效范圍為當前shell及其子子孫孫shell進程

    變量聲明、賦值:

export name=VALUE

declare -x name=VALUE

    變量引用:$name, ${name}

    顯示所有環境變量:

export

env

printenv

    刪除:unset name

    bash 有許多內建的環境變量:PATH, SHELL, USRE,UID,HISTSIZE,HOME,PWD,OLDPWD,HISTFILE,PS1

5、只讀變量:只能聲名,但不能修改和刪除

readonly name=value

declare -r name=value

6、位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數

$1, $2, … :對應第1 、第2 等參數(但是地址變量$10指的是第一個參數$1和0的組合,例如$1參數是x,那么$10就是x0)

$0: 命令本身,例如/root/bin/arg.sh

$*: 傳遞給腳本的所有參數,全部參數合為一個字符串

$@: 傳遞給腳本的所有參數,每個參數為獨立字符串

$#: 傳遞給腳本的參數的個數

$@ $* 只在被雙引號包起來的時候才會有差異

例如f1.sh腳本#!/bin/bash

f2.sh “$*”

f2.sh “$@”

7、算術運算

bash 中的算術運算:

+, -, *, /, % (取余), ** (乘方)

實現算術運算:

(1) let var= 算術表達式

(2) var=$[ 算術表達式]

(3) var=$(( 算術表達式))

(4) echo ‘算術表達式’ | bc

   乘法符號有些場景中需要轉義,如*

   bash 有內建的隨機數生成器:$RANDOM (1-32767)

echo $[$RANDOM%50] 生成0-49 之間隨機數

8、賦值

增強型賦值:+=, -=, *=, /=, %=

   let varOPERvalue

例如:let count+=3,意思是變量count自加3 后自賦值

let var++

let var—

后置加加和前置加加
i++
表示i的值作為表達式的值,然后i自加1
++i
表示i先自加1再作為表達式的值

9、邏輯運算

true, false

      1, 0

 與:

1 與 1 = 1

1 與 0 = 0

0 與 1 = 0

0 與 0 = 0

 或:

1 或 1 = 1

1 或 0 = 1

0 或 1 = 1

0 或 0 = 0

命令true,#true命令執行后#echo $?的返回值是0

命令false,#false命令執行后#echo $?的返回值是非零任意數

短路與&&:exp1 如果為假,exp2就不運算;也是exp1為真,exp2就運算

短路或||:exp1 如果為真,exp2就不運算;也是exp1為假,exp2就運算

異或^:exp1與exp2相同為假,不同為真

10、聚集命令

    有兩種聚集命令的方法:

? 復合式:date; who | wc –l   命令會一個接一個地運行

? 子shell式 :(date; who | wc -l ) >> /tmp/trace 所有的輸出都被發送給單個STDOUT 和STDERR

11、退出狀態

進程可以使用退出狀態來報告成功或失敗

$? 變量保存最近的命令退出狀態,可以在腳本中使用,保存的是前一個緊挨著的命令的執行狀態

#echo $? 返回值為0代表成功,1-255 代表失敗

例如:

#ping -c1 -W1 hostIP &> /dev/null

# echo $?

   (第一條命令中:-c1選項表示ping一次,-W1表示1秒)

12、退出狀態碼

exit [n]:自定義退出狀態碼

例如,在腳本中最后一行寫入exit 99,則腳本運行結束后,無論腳本倒數第二行的命令成功或者失敗,則查看退出狀態時#echo $?的返回值都是99

注意:腳本中一旦遇到exit 命令,腳本會立即終止,終止退出狀態取決于exit 命令后面的數字,若exit命令后無數字,則終止退出狀態碼取決于此exit命令前一條命令的執行結果成敗取0或者非零的任意數

注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼

13、條件測試

測試命令:

? test EXPRESSION

? [ EXPRESSION ]

? [[ EXPRESSION ]],雙中括號有更強適用性

注意:若使用第二、三條測試命令,則EXPRESSION 前后必須有空白字符

&&與||是條件性的執行操作符

示例(雙引號):

$ test "$A" == "$B" && echo "Strings are equal"

$ test “$A” -eq “$B” && echo "Integers are equal"

簡寫格式的例子:

$ [ "$A" == "$B" ] && echo "Strings are equal"

$ [ "$A" -eq "$B" ] && echo "Integers are equal"

14、bash 的測試類型

    1)、數值測試:

-gt:  是否大于;

-ge:  是否大于等于;

-eq:  是否等于;

-ne:  是否不等于;

-lt:  是否小于;

-le:  是否小于等于;

     2)、字符串測試:

== :是否等于;

>: ascii碼是否大于ascii碼

<: 是否小于

!=: 是否不等于

=~: 左側字符串是否能夠被右側的PATTERN所匹配

(注意:  此上表達式一般用于[[ ]]中)

-z "STRING" :字符串是否為空,空為真,不空為假

-n "STRING" :字符串是否為空,不空為真,空為假

(注意:用于字符串比較時的用到的操作數都應該使用引號)

3)、文件測試

     存在性測試

-a FILE :同-e

-e FILE : 文件存在性測試,存在為真,否則為假;

    存在性及類別測試

-b FILE :是否存在且為塊設備文件

-c FILE :是否存在且為字符設備文件

-d FILE :是否存在且為目錄文件

-f FILE :是否存在且為普通文件

-h FILE 或 -L FILE :是否存在且為符號鏈接文件

-p FILE :是否存在且為命名管道文件

-S FILE :是否存在且為套接字文件

文件權限測試:-r、-w、-x

    文件特殊權限測試:

-g FILE :是否存在且擁有sgid 權限

-u FILE :是否存在且擁有suid 權限

-k FILE :是否存在且擁有sticky權限

文件大小測試:

-s FILE:  是否存在且非空,也即非空為真,#[ -s FILE ]執行后#echo $?的返回值是0

    文件是否打開:

-N FILE :文件自上一次被讀取之后是否被修改過,也即是atime在mtime前就是自上一次讀取后被修改過,#[ -N FILE ]執行后#echo $?的返回值是0

-O FILE :當前有效用戶是否為文件屬主

-G FILE :當前有效用戶是否為文件屬組

    雙目測試:

FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode,也即是FILE1與FILE2是否是硬鏈接的關系,如是為真,不是為假

FILE1 -nt/-ot FILE2: FILE1是否新/舊于FILE2,比較的是FILE1與FILE2的修改時間,也即mtime

15、組合測試條件

    第一種方式:

COMMAND1 && COMMAND2  并且

COMMAND1 || COMMAND2  或者

! COMMAND

如:[ -e FILE ] && [ -r FILE ]

    第二種方式:

EXPRESSION1 -a EXPRESSION2  并且

EXPRESSION1 -o EXPRESSION2  或者

! EXPRESSION

如:# [ -z “$HOSTNAME” -o "$HOSTNAME" =="localhost.localdomain" ] && hostname www.magedu.com

    主機名為空或者是localhost.localdomain,那么就定義主機名為www.magedu.com

# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

如果/bin/cat是存在且為普通文件并且/bin/cat有執行權限,那么就執行cat /etc/fstab

16、使用read 命令來接受輸入

read 從標準輸入即鍵盤輸入中讀取值,分配給一個或多個shell變量

-p 指定要顯示的提示信息

用法:read -p “Enter a filename:” FILE

示例:指定文件做為參數,編寫腳本判斷文件是否為.sh后綴,如果是,添加x權限;不是,則提示xxf

#!/bin/bash

read -p "please input the file:" a

A1=`echo $a | grep -o "\.[^.]\+$"`

[[ "$A1" == ".sh" ]] && chmod +x $a || echo xxf

17、腳本example.sh未賦予權限時,使用bash、source及 .

1)、使用bash運行相當于開了一個子shell example.sh,example.sh里面的變量當前終端shell不可引用;

2)、使用source和 .運行example.sh腳本,就相當于直接在當前終端運行腳本example.sh內變量和命令代碼,所有example.sh里面的變量可以為當前終端shell引用

所以可知,bash是給腳本用的,source和 .是給配置文件使用的

例如example.sh腳本位于當前root用戶的家目錄下,為#!/bin/bash

                                                   a=haha

                                                   PATH=/XXX

                                                   echo PATH=$PATH

                                                   cd /tmp

那么如果使用source或者 .來運行腳本example.sh,比如# . /root/example.sh后

輸出的結果是PATH=/XXX,同時當前的目錄變為/tmp,實際上變量a和PATH是定義于當前終端上了,故而

再#echo $a 的輸出結果是haha,而不是為空

  #echo $PATH 的輸出結果是/XXX,而不再是默認的PATH路徑,因為原先的PATH變量被替換

  #pwd 的返回值是/tmp,而不是當前root用戶的家目錄/root


原創文章,作者:18612763863,如若轉載,請注明出處:http://www.www58058.com/35548

(0)
1861276386318612763863
上一篇 2016-08-15 09:24
下一篇 2016-08-15 09:24

相關推薦

  • 淺談linux基礎知識(一)

    一:計算機的組成 組成: 計算機的主要組成部分為計算機硬件、軟件。 計算機硬件系統包括: 主機和外部設備。 主機包括:運算器、控制器、存儲器(只讀ROM、隨機RAM)。 外部設備主要包括:輸入設備、輸出設備、外存儲器和其他。 軟件包括: 應用軟件、系統軟件。 二:linux的發行版及不同發行版之間的聯系和區別。 1.Debian(唯一一個無商業公司支持的社區…

    Linux干貨 2016-09-18
  • N22+張zhangzhang+第6周博客作業

    請詳細總結vim編輯器的使用并完成以下練習題   vim編輯器是vi編輯器的增強版,是全屏文本編輯器,用于完成文本的輸出、刪除、查找、替換、塊操作等眾多功能。一般分三種模式:編輯模式、輸入模式、末行模式。 vim各種按鍵的功能 編輯模式: 1、復制/etc/rc.d/rc.sysinit文件至/tmp目錄,將/tmp/rc.sysinit文件中的以…

    Linux干貨 2016-09-20
  • CentOS6.8啟動卡死在開機進度條

    不知道什么原因CentOS6.8開機的時候卡在進度條一直進不去。就是下面的畫面 在這個畫面下面也看不到什么原因,果斷F5切換至有顯示開機進程的界面 看到了上述的錯誤提示:invalid user :'root' root是無效的root這是什么鬼? 接下來重新開機,進入到救援模式 開機的時候快速按一下ESC,進入到CD啟動,然后選擇救援模…

    Linux干貨 2016-12-08
  • Liunx獲取信息幫助與man文檔章節的劃分

    首先要判斷命令的類型,可用 type COMMAND 來判斷命令 如果顯示結果為(….是 shell內嵌)即為shell內嵌命令,如需獲取幫助,使用 help COMMAND 即可; 下圖的例子是pwd是shell內嵌命令 內部命令屬于Shell的一部分,所以并沒有單獨對應的系統文件,只要Shell解釋器被運行,內部指…

    2017-07-02
  • Python線程指南

    本文介紹了Python對于線程的支持,包括“學會”多線程編程需要掌握的基礎以及Python兩個線程標準庫的完整介紹及使用示例。 注意:本文基于Python2.4完成,;如果看到不明白的詞匯請記得百度谷歌或維基,whatever。 尊重作者的勞動,轉載請注明作者及原文地址 >.< 1. 線程基礎 1.1. 線程狀態 線程有5種狀態,狀態轉換的過程如…

    2015-03-13
  • 設計模式 ( 十三 ) 命令模式Command(對象行為型)

    1.概述         在軟件設計中,我們經常需要向某些對象發送請求,但是并不知道請求的接收者是誰,也不知道被請求的操作是哪個,我們只需在程序運行時指定具體的請求接收者即可,此時,可以使用命令模式來進行設計,使得請求發送者與請求接收者消除彼此之間的耦合,讓對象之間的調用關系更加靈活。  例子1:電視機遙控器…

    Linux干貨 2015-07-16
欧美性久久久久