01- Shell腳本學習--入門


簡介

Shell是一種腳本語言,那么,就必須有解釋器來執行這些腳本。

Unix/Linux上常見的Shell腳本解釋器有bash、sh、csh、ksh等,習慣上把它們稱作一種Shell。我們常說有多少種Shell,其實說的是Shell腳本解釋器。

Hello World

打開文本編輯器,新建一個文件test.sh,擴展名為.sh(sh代表shell)。

輸入一些代碼:

#!/bin/bash
echo "Hello World !"

在命令行運行:

chmod +x test.sh
./test.sh

運行結果:

Hello World !

#! 是一個約定的標記,它告訴系統這個腳本需要什么解釋器來執行,即使用哪一種Shellecho命令用於向窗口輸出文本。

注釋

#開頭的行就是注釋,會被解釋器忽略。sh里沒有多行注釋,只能每一行加一個#號。

# --------
# 這是注釋塊
# --------

打印輸出

echo: 是Shell的一個內部指令,用於在屏幕上打印出指定的字符串。

echo arg 
echo -e arg #執行arg里的轉義字符。echo加了-e默認會換行
echo arg > myfile #顯示結果重定向至文件,會生成myfile文件

注意,echo后單引號和雙引號作用是不同的。單引號不能轉義里面的字符。雙引號可有可無,單引號主要用在原樣輸出中。

printf:格式化輸出語句。
printf 命令用於格式化輸出, 是echo命令的增強版。它是C語言printf()庫函數的一個有限的變形,並且在語法上有些不同。

如同 echo 命令,printf 命令也可以輸出簡單的字符串:

printf "hello\n"

printf 不像 echo 那樣會自動換行,必須顯式添加換行符(\n)。

注意:printf 由 POSIX 標准所定義,移植性要比 echo 好。

printf 命令的語法:

printf  format-string  [arguments...]

#format-string 為格式控制字符串,arguments 為參數列表。功能和用法與c語言的 printf 命令類似。

這里僅說明與C語言printf()函數的不同:

  • printf 命令不用加括號
  • format-string 可以沒有引號,但最好加上,單引號雙引號均可。
  • 參數比格式控制符(%)多時,格式控制符可以重用,可以將所有參數都轉換。
  • arguments 使用空格分隔,不用逗號。
# 雙引號
printf "%d %s\n" 10 "abc"
10 abc
# 單引號與雙引號效果一樣 
printf '%d %s\n' 10 "abc" 
10 abc

# 沒有引號也可以輸出
printf %s abc
abc

# 但是下面的會出錯:
printf %d %s 10 abc 
#因為系統分不清楚哪個是參數,這時候最好加引號了。


# 格式只指定了一個參數,但多出的參數仍然會按照該格式輸出,format-string 被重用
$ printf %s a b c
abc
$ printf "%s\n" a b c
a
b
c

# 如果沒有 arguments,那么 %s 用NULL代替,%d 用 0 代替
$ printf "%s and %d \n" 
and 0

# 如果以 %d 的格式來顯示字符串,那么會有警告,提示無效的數字,此時默認置為 0
$ printf "The first program always prints'%s,%d\n'" Hello Shell
-bash: printf: Shell: invalid number
The first program always prints 'Hello,0'
$

read: 命令行從輸入設備讀入內容

#!/bin/bash

# Author : lalal

echo "What is your name?"
read NAME #輸入
echo "Hello, $NAME"

運行腳本:

chmod +x test.sh
./test.sh

What is your name?
lalal

Hello, lalal

變量定義

Shell支持自定義變量。

定義變量

定義變量時,變量名不加美元符號($),如:

variableName="value"

注意,變量名和等號之間不能有空格,這可能和你熟悉的所有編程語言都不一樣。有空格會出錯。

同時,變量名的命名須遵循如下規則:

  • 首個字符必須為字母(a-z,A-Z)。
  • 中間不能有空格,可以使用下划線(_)。
  • 不能使用標點符號。
  • 不能使用bash里的關鍵字(可用help命令查看保留關鍵字)。

變量定義舉例:

myUrl="lalal"
myNum=100

使用變量

使用一個定義過的變量,只要在變量名前面加美元符號($)即可,如:

your_name="lalal"
echo $your_name
echo ${your_name}

變量名外面的花括號是可選的,加不加都行,加花括號是為了幫助解釋器識別變量的邊界,比如下面這種情況:

for skill in C PHP Python Java 
do
    echo "I am good at ${skill}Script"
done

如果不給skill變量加花括號,寫成echo "I am good at $skillScript",解釋器就會把$skillScript當成一個變量(其值為空),代碼執行結果就不是我們期望的樣子了。

推薦給所有變量加上花括號,這是個好的編程習慣。

已定義的變量,可以被重新定義。

在變量前面加readonly 命令可以將變量定義為只讀變量,只讀變量的值不能被改變。

url="http://www.baidu.com"
readonly url
url="http://www.baidu.com"

使用 unset 命令可以刪除變量。語法:

unset variable_name

變量被刪除后不能再次使用;unset 命令不能刪除只讀變量。

變量類型

運行shell時,會同時存在三種變量:
1) 局部變量
局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啟動的程序不能訪問局部變量。

2) 環境變量
所有的程序,包括shell啟動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。

3) shell變量
shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行。

特殊變量

前面已經講到,變量名只能包含數字、字母和下划線,因為某些包含其他字符的變量有特殊含義,這樣的變量被稱為特殊變量

變量 含義
$0 當前腳本的文件名
$n 傳遞給腳本或函數的參數。n 是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2
$# 傳遞給腳本或函數的參數個數。
$* 傳遞給腳本或函數的所有參數。
$@ 傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與 $* 稍有不同
$? 上個命令的退出狀態,或函數的返回值。
$$ 當前Shell進程ID。對於 Shell 腳本,就是這些腳本所在的進程ID。

示例:

#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"

運行結果:

$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2

$*$@ 的區別

$*$@ 都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。

但是當它們被雙引號(" ")包含時,"$*" 會將所有的參數作為一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。

示例:

#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\$@=" $@
echo "\"\$@\"=" "$@"
echo "print each param from \$*"
for var in $*
do
    echo "$var"
done
echo "print each param from \$@"
for var in $@
do
    echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
    echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
    echo "$var"
done

執行 ./test.sh "a" "b" "c" "d",看到下面的結果:

$*=  a b c d
"$*"= a b c d
$@=  a b c d
"$@"= a b c d
print each param from $*
a
b
c
d
print each param from $@
a
b
c
d
print each param from "$*"
a b c d
print each param from "$@"
a
b
c
d

退出狀態

$? 可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行后的返回結果。

示例:

if [[ $? != 0 ]];then
  echo "error"
  exit 1;
fi

退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。

不過,也有一些命令返回其他值,表示不同類型的錯誤。

轉義字符

轉義字符	含義
\\	反斜杠
\a	警報,響鈴
\b	退格(刪除鍵)
\f	換頁(FF),將當前位置移到下頁開頭
\n	換行
\r	回車
\t	水平制表符(tab鍵) 
\v	垂直制表符

shell默認是不轉義上面的字符的。需要加-e選項。

舉個例子:

#!/bin/bash
a=11
echo -e "a is $a \n"

運行結果:

Value of a is 10

這里 -e 表示對轉義字符進行替換。如果不使用 -e 選項,將會原樣輸出:

Value of a is 10\n

可以使用 echo 命令的 -E 選項禁止轉義,默認也是不轉義的;使用 -n 選項可以禁止插入換行符。

命令替換

命令替換是指Shell可以先執行命令,將輸出結果暫時保存,在適當的地方輸出。

語法:

`command`

注意是反引號,不是單引號,這個鍵位於 Esc 鍵下方。

下面的例子中,將命令執行結果保存在變量中:

#!/bin/bash
DATE=`date`
echo "Date is $DATE"

變量替換

變量替換可以根據變量的狀態(是否為空、是否定義等)來改變它的值。

可以使用的變量替換形式:

形式 說明
${var} 變量本來的值
${var:-word} 如果變量 var 為空或已被刪除(unset),那么返回 word,但不改變 var 的值。
${var:=word} 如果變量 var 為空或已被刪除(unset),那么返回 word,並將 var 的值設置為 word。
${var:?message} 如果變量 var 為空或已被刪除(unset),那么將消息 message 送到標准錯誤輸出,可以用來檢測變量 var 是否可以被正常賦值。若此替換出現在Shell腳本中,那么腳本將停止運行。
${var:+word} 如果變量 var 被定義,那么返回 word,但不改變 var 的值。

一個完整的shell示例

下面的腳本用於php安裝過程中安裝zip擴展。

php_zip_ins.sh

#!/bin/bash
#zip install

if [ -d php-5.4.25/ext/zip ];then
	cd php-5.4.25/ext/zip
else
	tar zxvf php-5.4.25.tar.gz
	cd php-5.4.25/ext/zip
fi
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
[ $? != 0 ] && exit
make install
echo 
grep 'no-debug-zts-20100525' /usr/local/php/etc/php.ini
if [ $? != 0 ];then
        echo '' >> /usr/local/php/etc/php.ini
        echo 'extension_dir=/usr/local/php/lib/php/extensions/no-debug-zts-20100525' >> /usr/local/php/etc/php.ini
fi
grep 'zip.so' /usr/local/php/etc/php.ini
if [ $? != 0 ];then
	echo 'extension=zip.so' >> /usr/local/php/etc/php.ini
fi
echo "zip install is OK"


/usr/local/apache2/bin/apachectl restart
cd -
rm -rf php-5.4.25
echo "all ok!"
ls /usr/local/php/lib/php/extensions/no-debug-zts-20100525/

Shell腳本學習系列教程github: https://github.com/52fhy/shell-book


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM