使用者工具

網站工具


linux:shell

這是本文件的舊版!


Linux Shell Scripting Tutorial

bash 環境設定

可用 set 指令查看現有的環境變數

設定檔

讀取順序

  1. /etc/profile
  2. ~/.bash_profile
  3. ~/.bash_login
  4. ~/.profile
環境變數 說明
HOME 家目錄
MAIL 郵件儲存位置
PS1 第一個提示符號,等待使用者命令
PS2 第二個提示符號,收到的指令不完整,等待使用者繼續輸入
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$
PS2='> '
控制字 功能
\a 一嗶聲
\e 跳脫字元
\H 主機名稱(較長格式)
\h
\n 換行
\s Shell Name
\T 以 12 小時制顯示時間
\t
\@
\u 使用者名稱
\W 完整工作目錄
\w 目前目錄
\$ root 會顯示「#」,一般使用者則為「$」

印出反斜線

Shell Script

變數

直接指定變數的值,使用時前面加 $

vari = 5
echo "var = $vari"

指令參數

$ ./script.sh ~/temp.txt temp2.txt

此時,在程式中

$0 = ./script.sh
$1 = ~/temp.txt
$2 = temp2.txt
$* = ~/temp.txt temp2.txt    // 所有參數
$# = 2    // 參數個數

設定參數 set

將原本的參數換成新指令的輸出

set `date`
echo "$4 $5 $1 $3 $2 $6"

輸入 read

read input
echo $input

數學運算 expr

a=1
b=2
c=`expr $a + $b`    # 等號前後不可以有空白
echo $c

條件敘述

數值比較

若為 true 則傳回 1,false 為零

test a -eq b

^ 符號 ^意義^

-eq =
-ne !=
-lt <
-le < =
-gt >
-ge >=

字串比較

符號 意義
= str1 = str2
!= str1 != str2
-n 不是空字串
-z 空字串

檔案屬性測試

選項 意義
-l 是否為連結檔案
-d 目錄
-e 存在
-f 存在且為一般檔案
-r 存在且可讀
-w 存在且可寫
-x 存在且可執行
-nt 比較兩檔案修改時間,如: file1 -nt file2

if 的結構

if 條件判斷
then
  ...
fi

關鍵字要自成一行,若硬要同行,要用分號分隔,但 then 後面不用分號

if 條件 ; then ... ; fi
if test -f $1 ; then  echo "$1 is a reqular file." ; fi
if [ $1 -eq $2 ] ; then echo "equal" ; else echo "not equal" ; fi
if [ ! -e $1 ] ; then ... ; fi    # 如果 $1 的檔案不存在

以下兩行相同

if [ -r $1 ] && [ -x $1 ]
if (test -r $1) && (test -x $1)
if 條件
then
  ...
else
  ...
fi
if 條件
then
  ...
elif
then
  ...
else
  ...
fi

case 結構

每一 pattern 用兩個分號分隔,每一敘述用一個分號。

case variable in
pattern_1) [statement] ;;
pattern_2)
  [statement1];
  [statement2];;
...
esac
case $1 in
1) echo "One";;
2)
  echo "Two";
  echo "2";;
esac

pattern 可使用正規表示式:

case $1 in
*a) echo "End with a";;
*b) echo "b";;
esac

for 迴圈

List 中所有的元素接執行一次

for var in List
do
  ........
done
for file in `ls`
do
  if [ -f $var ] ; then echo "$file is a reqular file.";
done

while 迴圈

while 條件
do
  ......
done

until 迴圈

和 while 相反,在條件不成立時執行。

until 條件
do
  ......
done

select 迴圈

系統將 List 中的所有元素當作選項,並以環境變數 PS3 作為 Prompt,提示使用者輸入,當使用者輸入某個選項時執行 do done 間的程式。

select var in List
do
  ......
done
#!/bin/bash
PS3="INPUT: "
select var in `ls`
do
  if [ $var ]; then
    if [ -f $var ];then echo "$var reqular."
    else echo "$var no reqular."
    fi
  else echo "Bad input"
  fi
done

break , continue

可在後面接數字,代表要跳出哪個迴圈,如:break2 指要中斷第二個迴圈。

function

函數宣告必須在呼叫之前完成,因為 Shell script 是直譯程式,且需注意:1. 全域和區域變數的範圍;2. 傳參數的用法。

Function name
{
  ......
}

function_name()
{
  ......
}

變數的生命週期

有三種不同性質的變數。

環境變數

由系統產生,必定是全域變數。

位置變數

由函式被呼叫時所附加的參數而定,因此必為區域變數,在不同的函式用同樣的方法使用,但數值不同。

$1, $2, $3, ... 

自訂變數

除非特別指定成 local,不然皆為全域變數。

local var1="string"
#!/bin/bash
funct () {
    echo "Inside  -- funct: $# args: $1 $2 $3"
}
echo "Outside -- $0: $# args: $1 $2 $3"
funct input1 input2 input3    // 呼叫函式
$ ./test.sh in1 in2 in3
Outside -- ./test.sh: 3 args: in1 in2 in3
Inside  -- funct: 3 args: input1 input2 input3

參數傳遞

  • 傳入函式:呼叫時直接寫在函式名稱後面,即可成為函式的位置變數
  • 傳出函式:使用全域變數來儲存跨函式間的資料

定期確認 apache 的 error log

#! /bin/bash

for x in `grep "File does not exist:" /var/log/apache2/error.log | awk '{print $13}' | sort | uniq`;
do
   grep $x /var/log/apache2/error.log | wc -l | tr -d '\n';
   echo " : $x";
done | sort -rn | head -20

並在 crontab 中加入(需 root 權限)

0  21    *   *   5    /root/apache_file_no_found_error.sh
linux/shell.1175182464.txt.gz · 上一次變更: 2007/03/29 23:41 (外部編輯)