顯示具有 shell script 標籤的文章。 顯示所有文章
顯示具有 shell script 標籤的文章。 顯示所有文章

2017年12月3日 星期日

『Bash Shell』如何使用內建指令 local Command 宣告區域變數 程式範例/完整說明

全域變數與區域變數的宣告有底下兩件事情要注意

1. 在 shell script 或 function 內宣告變數時,都是全域變數。

範例:

#!/bin/sh

var0="global_var0"

function local_var()
{
        declare -p var0
        var1="global_var1"
        declare -p var1
}

declare -p var0
local_var
declare -p var1

結果:

declare -- var0="global_var0"
declare -- var0="global_var0"
declare -- var1="global_var1"
declare -- var1="global_var1"

說明:

範例中使用 declare -p 來看變數是否存在,在 shell script 內宣告的 var0,在 local_var() 函式也是存在,表示 var0 是全域變數。而 var1 是在 local_var() 函式內宣告,但是離開 local_var() 函式後,var1 還是存在,表示 var1 也是全域變數。

2. 區域變數需要使用 local Command 來宣告,但只有函式 function 內可以使用 local Command 來宣告區域變數。

範例:



#!/bin/sh



function local_var()

{
        local var1="global_var1"
}

local_var
declare -p var1

local var0="global_var0"

結果:

./local_cmd2.sh: line 9: declare: var1: not found
./local_cmd2.sh: line 11: local: can only be used in a function

說明:

1. var1 是在 local_var() 函式內宣告,離開 local_var() 函式後,var1 不存在,表示 var1 是區域變數。

2. 在 shell script 內使用 local Command 宣告 var0 發生錯誤,因為 local Command 只能在函式 function 中被使用。

好站連結
1. http://linux.vbird.org/linux_basic/0320bash.php#variable_range

2017年12月2日 星期六

『Bash Shell』如何寫無窮迴圈 Infinite loop 程式範例/完整說明

無窮迴圈有一個很簡單的寫法,利用 builtin command ( : ) 與 while command。while command 的語法如下。

while test-commands; do consequent-commands; done

每當 test-commands 執行後的離開狀態(exit status)為零時,則執行 do 與 done 之間的 consequent-commands。

範例:

#/bin/sh

while :
do
        echo "This is a infinite loop."
        sleep 1
done

結果:

This is a infinite loop.
This is a infinite loop.

說明:

1. 此範例利用 builtin command ( : )的離開狀態(exit status)都會回傳零,表示成功的特性,搭配 while command 的迴圈功能,來達到無窮迴圈的效果。

2. 如要跳出這個無窮迴圈可以按 ctrl + c 把 script 停掉。

2017年12月1日 星期五

『Bash Shell』如何宣告變數 Variable 程式範例/完整說明

變數 Variable 用來儲存值 Value,變數的型態有四種
1. 整數 (Integer)
2. 索引式陣列 (Indexed Array)
3. 關聯式陣列 (Associative Array)
4. 字串 (String)

變數的型態以變數本身帶有的屬性來表示,屬性如下

1. 屬性 i: 有此屬性的變數是整數 (Integer)
2. 屬性 a: 有此屬性的變數是索引式陣列 (Indexed Array)
3. 屬性 A: 有此屬性的變數是關聯式陣列 (Associative Array)
4. 屬性 r: 有此屬性的變數表示變數值是唯讀 (Read-only)

注意:沒有 i, a, A 三種屬性的就算是字串型態


變數屬性要怎麼查詢可以參考如下文章

Bash Shell | 如何使用內建指令 declare Command

1. 宣告一個整數型態的變數時,使用 declare -i 後面加上變數名稱,語法如下


declare -i name[=value]


範例:


#!/bin/sh


declare -i var0=10


declare -i var1

var1=20

# The value of var2 will be zero if the value is not a number

declare -i var2=A

declare -p var0 var1 var2


結果:


declare -i var0="10"

declare -i var1="20"
declare -i var2="0"

說明:


因為 var2 宣告為整數型態,當 var2 的變數值被指定為非數字時,var2 的變數值變成0(此範例是指定為字元'A'),宣告為整數型態的好處是,做算術運算時不需要使用算數擴展 $(( expression ))。


範例:


#!/bin/sh


var0=10

var1=${var0}+1
echo $var1

declare -i var2=10 var3

var3=${var2}+1
echo $var3

declare -p var0 var1 var2 var3


var1=$(( var0 + 1 ))

echo $var1

declare -p var1


結果:


$var1 = 10+1

$var3 = 11
declare -- var0="10"
declare -- var1="10+1"
declare -i var2="10"
declare -i var3="11"
$var1 = 11
declare -- var1="11"

說明:

1. var0 與 var1 宣告為字串,因此 var1=${var0}+1 被當作字串連接處理,var1 結果為字串 10+1。
2. var2 與 var3 宣告為整數,因此 var3=${var2}+1 被當做整數加法處理,var3 的結果為整數 11。

2. 宣告一個索引式陣列的變數時,主要有兩種方式,語法如下

第一種

name[subscript]=value

第二種

declare -a name[=(value1 value2 ...)]

範例:


#!/bin/sh


array1[0]=a

array1[1]=b
array1[2]=c

declare -a array2=(d e f)

declare -p array1 array2


for i in {0..2}

do
    echo \$array1[$i] = ${array1[$i]}
done

for i in {0..2}
do
    echo \$array2[$i] = ${array2[$i]}
done

結果:



declare -a array1='([0]="a" [1]="b" [2]="c")'

declare -a array2='([0]="d" [1]="e" [2]="f")'

$array1[0] = a
$array1[1] = b
$array1[2] = c
$array2[0] = d
$array2[1] = e
$array2[2] = f

3. 宣告一個關聯式陣列的變數時,使用 declare -A 後面加上變數名稱,語法如下

declare -A name[=([key1]=value1 [key2]=value2 ...)]

範例:


#!/bin/sh


declare -A score_array=([william]=100 [neo]=80 [tom]=90)


declare -p score_array


echo \$score_array[william] = ${score_array[william]}

echo \$score_array[neo] = ${score_array[neo]}
echo \$score_array[tom] = ${score_array[tom]}

結果:


declare -A score_array='([tom]="90" [neo]="80" [william]="100" )'

$score_array[william] = 100
$score_array[neo] = 80
$score_array[tom] = 90

4. 宣告一個字串變數時,主要有兩種方式,語法如下

第一種

str1=[value]

第二種

declare str2[=value]

範例:

#!/bin/sh

str1="I am str1"


declare str2="I am str2"


declare str3

str3="I am str3"

declare -p str1 str2 str3


echo \$str1 = $str1

echo \$str2 = $str2
echo \$str3 = $str3

結果:

declare -- str1="I am str1"
declare -- str2="I am str2"
declare -- str3="I am str3"
$str1 = I am str1
$str2 = I am str2
$str3 = I am str3

5. 宣告唯讀屬性的變數,使用 declare -r 語法如下

declare -r name

範例:

#!/bin/sh

declare -ri var0=10
declare -ra array1=(a b c)
declare -rA score_array=([william]=100 [neo]=80 [tom]=90)
declare -r  str1="I am str1"

var0=11
array1[0]=A
score_array[neo]=60
str1="read-only"

結果:(對個別參數做設定時的錯誤訊息如下)

./declare_ro.sh: line 8: var0: readonly variable
./declare_ro.sh: line 9: array1: readonly variable
./declare_ro.sh: line 10: score_array: readonly variable
./declare_ro.sh: line 11: str1: readonly variable

好站連結
 1. http://linux.vbird.org/linux_basic/0320bash.php#variable

2017年11月30日 星期四

Bash Shell | 如何將程序的輸出入結果做為程式參數 Process Substitution

Process Substitution 有兩種使用方式
1. <(list)
   <(list) 整個可以視為一個檔名看待,因此可以當做另一個程式的參數使用,當然也可
   以當作 redirection 使用。想像 list 程式的輸出會存到一個暫存檔,讓另一個程
   式以參數的形式取得暫存檔,並讀取暫存檔的內容。

   使用多個參數的程式可以利用此功能,例如 cmp 會用到兩個參數,當要比較的內容是由
   其它程式的輸出而來,則不用先將其它程式的輸出分別存到暫存檔,再用 cmp 比較暫存
   檔。底下範例用來比較兩個目錄下是否有一樣的檔案名稱,但不支援子目錄的比較。

範例:

#!/bin/sh

mkdir -p folder1
mkdir -p folder2

touch folder1/file1
touch folder2/file2

# Disable POSIX mode because process substitution is not 
# available in POSIX mode
set +o posix

if cmp -s <(ls folder1) <(ls folder2); then
        echo "folder1 and folder2 are the same."
else
        echo "folder1 and folder2 are different."
fi

touch folder1/file2
touch folder2/file1

if cmp -s <(ls folder1) <(ls folder2); then
        echo "folder1 and folder2 are the same."
else
        echo "folder1 and folder2 are different."
fi

結果:

folder1 and folder2 are different.
folder1 and folder2 are the same.

2. >(list)
   >(list) 整個可以視為一個檔名看待,因此可以當做另一個程式的參數使用,當然也可
   以當作 redirection 使用,想像有一個暫存檔當做 list 程式的輸入,另一個程式
   以參數的形式取得暫存檔,對暫存檔的輸出都變成 list 程式的輸入。

Bash Shell | 如何使用內建指令 type Command

type 指令可以用來查詢某個指令的型態,可能的型態如下
1. 別名 (alias)
2. 函式 (function)
3. 內建指令 (builtin)
4. 檔案 (file)
5. 關鍵字 (keyword)

在終端機下執行底下指令,此範例執行 type 指令並傳入五個參數


範例:


type ls command_not_found_handle source cp if


結果:


ls is aliased to `ls --color=auto'

command_not_found_handle is a function
command_not_found_handle () 

    runcnf=1;
    retval=127;
    [ ! -S /var/run/dbus/system_bus_socket ] && runcnf=0;
    [ ! -x /usr/libexec/packagekitd ] && runcnf=0;
    if [ $runcnf -eq 1 ]; then
        /usr/libexec/pk-command-not-found $1;
        retval=$?;
    else
        echo "bash: $1: command not found";
    fi;
    return $retval
}
source is a shell builtin
cp is /bin/cp
if is a shell keyword

說明:


1. ls 是一個別名 (alias),也可以透過 alias 指令來查詢所有的別名。

2. command_not_found_handle 是一個函式 (function),也可以透過 set 看到函式原型
3. source 是 bash 的一個內建指令 builtin
4. cp 是一個檔案 (file),位置在 /bin 目錄底下
5. if 是一個 bash 的關鍵字 (keyword)

好站連結
1. http://linux.vbird.org/linux_basic/0320bash.php#bash_type