天天看點

Bash Shell學習筆記四

1. 幾個常用指令和基本知識。

set $(commond)          将位置參數設定為後面的指令輸出

shell指令中 在-- 後面的語句将會不再解釋後面的 -

cal 萬年曆

bc 電腦

$HISTSIZE 曆史大小

$RANDOM 随機數

basename  pathname    去除路徑字首的最後部分

空變量+1=1

沒有指派或申明的變量+1=1

字元變量--->通過替換成為數字-->數字變量  可以接受 +1操作

數字變量--->通過替換成為字元--->字元變量 不再接受 +1操作

使用-e 選項的echo 指令來列印轉義符

如果使用$'/X'結構,那-e 選項就不必要了

版本2 以後Bash 允許使用$'/nnn'結構,'/nnn/是8 進制

"[["是一個關鍵字,并不是一個指令

Bash 把[[ $a -lt $b ]]看作一個單獨的元素,并且傳回一個退出碼.

2.bash shell 數組的用法

數組申明方式:空格分隔的,()包含的字元

var=(ab sc linfe)

數組引用方式

first=$var[1] 引用第二個元素

first=$var[0] 或者 first=$var 引用第一個元素

擷取整個數組

whole=$var[@]

echo $whole

擷取數組的最大長度

long=${#var[@]}

echo $long

數組第N個元素字元串的長度

long=${#var[2]} 數組第3個元素的長度

擷取一部分數組内容

part=${#var[@]:1:2}

echo $part                    擷取從第2個元素開始 3個元素的内容

part=${$var[@]::2}     擷取從開始到第3個元素的内容

echo $part

part=${#var[@]:2}      擷取從第3個元素開始的内容

echo $part

數組的應用:模拟棧

push:

array=(”${array[@]}” $new_element)

pop:

array=(${array[@]:0:$((${#array[@]}-1))})

shift:

array=(${array[@]:1})

unshift

array=($new_element “${array[@]}”)

function del_array {

local i

for (( i = 0 ; i < ${#array[@]} ; i++ ))

do

if [ "$1" = "${array[$i]}" ] ;then

break

fi

done

del_array_index $i

}

function del_array_index {

array=(${array[@]:0:$1} ${array[@]:$(($1 + 1))})

}

3.bash中的特殊字元

$ 數制轉換  echo $((2#101011)) 傳回101011的十進制結果

:内建指令,傳回值為0,指令的結果傳回為0表示true,什麼也不做

${HOSTNAME?} 判斷HOSTNAME是否被set

() 指令組,在()中的指令清單,将作為一個子shell來運作

$? 前一個指令的退出狀态

$$ 程序的pid

$*,[email protected] 位置參數

${ }參數替換

$ 正規表達式中的行結束符

? 正規表達式中的單個字元

? (())結構中,用來做3元操作符

* 正規表達式中的萬能比對

** 數學幂運算

{}  大括号擴充 cat {file1,file2,filr3} > file   cp file{1,2}

^ 比對輸入字元串的開始位置。

$  比對輸入字元串的結束位置。

~+ 等同于 $PWD 目前目錄

~-  等同于 $OLDPWD 上一個目錄

args=$#;lastarg=${!args} 參數傳遞中第一個為$1,$#表示總個數,最後一個為 $lastarg

[ -n $var]  var是否被定義,定義則為真 與 [ -z $var ]測試相反

4.bash shell 中有用的結構

until [ -z "$1" ]

do

echo -n "$1 "

shift

done

if grep -q file

then

echo ""

fi

case "$variable" in

abc) commond ;;

xyz) commond ;;

esac

5.如何在檔案的第一行插入文字

sed -i s/^/abc/n/ file

6.stty指令詳解

轉自:http://hi.baidu.com/rakeliujie/blog/item/629c91907ac4be88a877a408.html

簡潔方式,顯示波特率

stty

speed 38400 baud; line = 0;

eol = M-^?; eol2 = M-^?; swtch = M-^?;

ixany iutf8

顯示全部設定的指令

stty -a

speed 38400 baud; rows 24; columns 80; line = 0;

intr = ^C; quit = ^/; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;

swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;

lnext = ^V; flush = ^O; min = 1; time = 0;

-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts

-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff

-iuclc ixany imaxbel iutf8

opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0

isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt

echoctl echoke

重要一點

    屬性前面的減号表示被禁止

    沒有減号說明使能

上面一堆在struct termios{} 中有對應位,或者對應字元,c_cc[]内為對應字元

在include/asm-i386/termbits.h中定義這個結構及相應位

struct termios {

    tcflag_t c_iflag;       

    tcflag_t c_oflag;       

    tcflag_t c_cflag;       

    tcflag_t c_lflag;       

    cc_t c_line;           

    cc_t c_cc[NCCS];       

};

輸入模式

c_iflag包含如下标志:

#define IGNBRK    0000001

#define BRKINT    0000002

#define IGNPAR    0000004

#define PARMRK    0000010

#define INPCK    0000020

#define ISTRIP    0000040

#define INLCR    0000100

#define IGNCR    0000200

#define ICRNL    0000400

#define IUCLC    0001000

#define IXON    0002000

#define IXANY    0004000

#define IXOFF    0010000

#define IMAXBEL    0020000

#define IUTF8    0040000

brkint     中斷時發出 INTR 信号。

-brkint     中斷時不發出 INTR 信号。

icrnl     輸入時将 CR 映射為 NL。

-icrnl     輸入時不将 CR 映射為 NL。

ignbrk     輸入時忽略 BREAK。

-ignbrk     輸入時不忽略 BREAK。

igncr     輸入時忽略 CR。

-igncr     輸入時不忽略 CR。

ignpar     忽略奇偶錯誤。

-ignpar     不忽略奇偶錯誤。

inlcr     輸入時将 NL 映射為 CR。

-inlcr     輸入時不将 NL 映射為 CR。

inpck     啟用奇偶校驗。

-inpck     禁用奇偶校驗。

istrip     将輸入字元剝離到 7 位。

-istrip     不将輸入字元剝離到 7 位。

iuclc     将大寫字母字元映射為小寫。

-iuclc     不将大寫字母字元映射為小寫。

ixany     允許任何字元重新啟動輸出。

-ixany     隻允許 START(Ctrl-Q 按鍵順序)重新啟動輸出。

ixoff     當輸入隊列接近空或滿時,發送 START/STOP 字元。

-ixoff     不發送 START/STOP 字元。

ixon         啟用 START/STOP 輸出控制。一旦啟用 START/STOP 輸出控制,

            您可以按下 Ctrl-S 按鍵順序暫停向工作站的輸出,也可按下 Ctrl-Q 按鍵順序恢複輸出。

-ixon     禁用 START/STOP 輸出控制。

imaxbel     當輸入溢出時,回送 BEL 字元并且廢棄最後的輸入字元。

-imaxbel 當輸入溢出時,廢棄所有輸入。

parmrk     标記奇偶錯誤。

-parmrk     不标記奇偶錯誤[1]。

輸出模式

c_oflag包含如下标志:

#define OPOST    0000001

#define OLCUC    0000002

#define ONLCR    0000004

#define OCRNL    0000010

#define ONOCR    0000020

#define ONLRET    0000040

#define OFILL    0000100

#define OFDEL    0000200

#define NLDLY    0000400

#define   NL0    0000000

#define   NL1    0000400

#define CRDLY    0003000

#define   CR0    0000000

#define   CR1    0001000

#define   CR2    0002000

#define   CR3    0003000

#define TABDLY    0014000

#define   TAB0    0000000

#define   TAB1    0004000

#define   TAB2    0010000

#define   TAB3    0014000

#define   XTABS    0014000

#define BSDLY    0020000

#define   BS0    0000000

#define   BS1    0020000

#define VTDLY    0040000

#define   VT0    0000000

#define   VT1    0040000

#define FFDLY    0100000

#define   FF0    0000000

#define   FF1    0100000

bs0, bs1                  為倒退符選擇延遲樣式(bs0 表示沒有延遲)。

cr0, cr1, cr2, cr3     為 CR 字元選擇延遲樣式(cr0 表示沒有延遲)。

ff0, ff1     為換頁選擇延遲樣式(ff0 表示沒有延遲)。

nl0, nl1     為 NL 字元選擇延遲樣式(nl0 表示沒有延遲)。

ofill     使用延遲填充字元。

-ofill     使用延遲定時。

ocrnl     将 CR 字元映射為 NL 字元。

-ocrnl     不将 CR 字元映射為 NL 字元。

olcuc     輸出時将小寫字母字元映射為大寫。

-olcuc     輸出時不将小寫字母字元映射為大寫。

onlcr     将 NL 字元映射為 CR-NL 字元。

-onlcr     不将 NL 字元映射為 CR-NL 字元。

onlret     在終端 NL 執行 CR 功能。

-onlret     在終端 NL 不執行 CR 功能。

onocr     不在零列輸出 CR 字元。

-onocr     在零列輸出 CR 字元。

opost     處理輸出。

-opost     不處理輸出;即忽略所有其它輸出選項。

ofdel     使用 DEL 字元作為填充字元。

-ofdel     使用 NUL 字元作為填充字元。

tab0, tab1, tab2     為水準制表符選擇延遲樣式(tab0 表示沒有延遲)。

tab3                     擴充制表符至多個空格。

vt0, vt1             為垂直制表符選擇延遲樣式(vt0 表示沒有延遲)[1]。

控制模式

#define CBAUD    0010017

#define B0    0000000       

#define B50    0000001

#define B75    0000002

#define B110    0000003

#define B134    0000004

#define B150    0000005

#define B200    0000006

#define B300    0000007

#define B600    0000010

#define B1200    0000011

#define B1800    0000012

#define B2400    0000013

#define B4800    0000014

#define B9600    0000015

#define B19200    0000016

#define B38400    0000017

#define EXTA B19200

#define EXTB B38400

#define CSIZE    0000060

#define   CS5    0000000

#define   CS6    0000020

#define   CS7    0000040

#define   CS8    0000060

#define CSTOPB    0000100

#define CREAD    0000200

#define PARENB    0000400

#define PARODD    0001000

#define HUPCL    0002000

#define CLOCAL    0004000

#define CBAUDEX 0010000

#define    B57600 0010001

#define   B115200 0010002

#define   B230400 0010003

#define   B460800 0010004

#define   B500000 0010005

#define   B576000 0010006

#define   B921600 0010007

#define B1000000 0010010

#define B1152000 0010011

#define B1500000 0010012

#define B2000000 0010013

#define B2500000 0010014

#define B3000000 0010015

#define B3500000 0010016

#define B4000000 0010017

#define CIBAUD      002003600000   

#define CMSPAR      010000000000       

#define CRTSCTS      020000000000       

clocal      假定一行沒有數據機控制。

-clocal     假定一行帶有數據機控制。

cread     啟用接收器。

-cread     禁用接收器。

cstopb     每個字元選擇兩個停止位。

-cstopb     每個字元選擇一個停止位。

cs5, cs6, cs7, cs8     選擇字元大小。

hup, hupcl     最後關閉時挂起撥接上網。

-hup, -hupcl     最後關閉時不挂起撥接上網。

parenb     啟用奇偶性校驗的生成和檢測。

-parenb     禁用奇偶性校驗的生成和檢測。

parodd     選擇奇校驗。

-parodd     選擇偶校驗。

0     立即挂起電話線路。

speed     将工作站輸入和輸出速度設定為指定的 speed 數(以位/秒為機關)。

            并不是所有的硬體接口都支援所有的速度。

            speed 的可能值有:50、75、110、134、200、300、600、1200、1800、

            2400、4800、9600、19200、19.2、38400、38.4、exta 和 extb。

注:

exta、19200 和 19.2 是同義詞;extb、38400 和 38.4 是同義詞。

ispeed speed     将工作站輸入速度設定為指定的 speed 數(以位/秒為機關)。

                    并不是所有的硬體接口都支援所有的速度,而且并不是所有的硬體接口都支援該選項。

                    speed 的可能值與 speed 選項相同。

ospeed speed     将工作站輸出速度設定為指定的 speed 數(以位/秒為機關)。

                    并不是所有的硬體接口都支援所有的速度,而且并不是所有的硬體接口都支援該選項。

                    speed 的可能值與 speed 選項相同[1]。

本地模式

#define ISIG    0000001

#define ICANON    0000002

#define XCASE    0000004

#define ECHO    0000010

#define ECHOE    0000020

#define ECHOK    0000040

#define ECHONL    0000100

#define NOFLSH    0000200

#define TOSTOP    0000400

#define ECHOCTL    0001000

#define ECHOPRT    0002000

#define ECHOKE    0004000

#define FLUSHO    0010000

#define PENDIN    0040000

#define IEXTEN    0100000

echo      回送每個輸入的字元。

-echo     不回送字元。

echoctl     以 ^X(Ctrl-X)回送控制字元,X 是将 100 八進制加到控制字元代碼中給出的字元。

-echoctl     不以 ^X(Ctrl-X)回送控制字元。

echoe     以“backspace space backspace”字元串回送 ERASE 字元。

注:

該模式不保持對列位置的跟蹤,是以您可能在擦除制表符和轉義序列等符号時得到意外的結果。

-echoe     不回送 ERASE 字元,隻回送倒退符。

echok     在 KILL 字元後回送 NL 字元。

-echok     在 KILL 字元後不回送 NL 字元。

echoke     通過擦除輸出行上的每個字元,回送 KILL 字元。

-echoke     隻回送 KILL 字元。

echonl     回送 NL 字元。

-echonl     不回送 NL 字元。

echoprt     以 /(斜杠)和 / (反斜杠) 向後回送擦除的字元。

-echoprt     不以 /(斜杠)和 / (反斜杠) 向後回送擦除的字元。

icanon     啟用規範輸入(規範輸入允許使用 ERASE 和 KILL 字元進行輸入行的編輯)。

            請參閱 AIX 5L Version 5.2 Communications Programming Concepts 中的

             Line Discipline Module (ldterm) 中關于 canonical mode input 的讨論。

-icanon     禁用規範輸入。

iexten     指定從輸入資料中識别實作性定義的功能。

            要識别以下控制字元,

            需要設定 iexten:eol2、dsusp、reprint、discard、werase、lnext。

            與這些模式關聯的功能也需要設定 iexten:imaxbel、echoke、echoprt、echoctl。

-iexten     指定從輸入資料中識别實作性定義的功能。

isig         啟用對特殊控制字元(INTR、SUSP 和 QUIT 特殊控制字元)的字元檢查。

-isig     禁用對特殊控制字元(INTR、SUSP 和 QUIT 特殊控制字元)的字元檢查。

noflsh     不清除 INTR、SUSP 或 QUIT 控制字元之後的緩沖區。

-noflsh     清除 INTR、SUSP 或 QUIT 控制字元之後的緩沖區。

pending     下次讀操作暫挂或輸入到達時,要重新輸入從原始模式轉換為規範模式後被暫挂的輸入。

            暫挂是一個内部狀态位。

-pending     沒有文本暫挂。

tostop     為背景輸出發出 SIGTOU 信号。

-tostop     不為背景輸出發出 SIGTOU 信号。

xcase     在輸入中回送大寫字元,并在輸出顯示的大寫字元之前加上 / (反斜杠)。

-xcase     不在輸入時回送大寫字元[1]。

控制字元

#define VINTR 0

#define VQUIT 1

#define VERASE 2

#define VKILL 3

#define VEOF 4

#define VTIME 5

#define VMIN 6

#define VSWTC 7

#define VSTART 8

#define VSTOP 9

#define VSUSP 10

#define VEOL 11

#define VREPRINT 12

#define VDISCARD 13

#define VWERASE 14

#define VLNEXT 15

#define VEOL2 16

控制指定

要将一個控制字元指定到某字元串中,請輸入:

stty Control String

其中,Control 參數可以是 INTR、QUIT、ERASE、KILL、EOF、EOL、EOL2、START、STOP、

SUSP、DSUSP、REPRINT、DISCARD、WERASE、

LNEXT、MIN 或 TIME 參數。(使用字元 MIN 和 TIME 時,請加上 -icanon 選項。)[1]

試驗

列印出終端的行數和列數

stty size

24 80

即24行,80列

stty cols 25

把列設為25行,發現輸出變窄

stty -a

speed 38400 baud;

rows 24; columns 25;

line = 0;

intr = ^C; quit = ^/;

erase = ^?; kill = ^U;

eof = ^D; eol = <undef>;

eol2 = <undef>;

swtch = <undef>;

start = ^Q; stop = ^S;

susp = ^Z; rprnt = ^R;

werase = ^W; lnext = ^V;

flush = ^O;

min = 1; time = 0;

-parenb -parodd cs8 hupcl

-cstopb cread -clocal

-crtscts

-ignbrk brkint ignpar

-parmrk -inpck istrip

-inlcr -igncr icrnl ixon

-ixoff -iuclc -ixany

imaxbel -iutf8

opost -olcuc -ocrnl onlcr

-onocr -onlret -ofill

-ofdel nl0 cr0 tab0 bs0

vt0 ff0

isig icanon iexten echo

echoe echok -echonl

-noflsh -xcase -tostop

-echoprt echoctl echoke

stty speed

顯示速率

stty intr c

c變為中斷鍵,想輸入c不可能了。

stty raw

發現ctrl+c不管用了,輸出混亂

允許原始模式輸入(不包括輸入處理,例如 erase、kill 或 interrupt);傳回奇偶(校驗)位。

stty -raw

允許規範輸入方式。

在指令行下,禁止輸出大寫的方法

stty iuclc #開啟

stty -iuclc #恢複

在指令行下禁止輸出小寫

stty olcuc #開啟

stty -olcuc#恢複

stty sane

将參數重新設定為合理的值。

忽略回車符

stty igncr #開啟

發現enter不起作用了,要顯示執行效果,需用ctrl+j

stty -igncr#恢複,要顯示執行效果,需用ctrl+j

stty erase x

倒退删除鍵變成x,想輸入x,不可能了,因為x是倒退鍵

stty erase ^?傳回原來倒退鍵

stty -echo

發現按鍵,什麼也沒有出現

stty echo

輸入顯示

stty -icanon

關閉驅動程式中的規範模式處理,跳過緩沖層,使用者不能删除字元,

測試一下

gui.c

#include<stdio.h>

main()

{

    char c;

    FILE *fp_tty;

    fp_tty=fopen("/dev/tty","r");

    if(fp_tty==NULL)

        exit(1);

    while((c=getc(fp_tty))!=EOF)

    {

        printf("%d",c);

    }

}

gcc gui.c -o gui

stty icanon

./gui

d

10010f

10210d

10010f

10210

可以用倒退鍵,并且顯示數字還得按Enter鍵, 從10( enter)就可以看出來

stty -icanon

./gui

d100f102g103h104

10

7.如何用sed直接替換文本而不重新生成檔案

指令

sed -i 's/pattern/replacement-string/ file

8.如何判斷變量不是空格的方法

指令

if [[ "a" != "a"$i ]]

then

       echo "not space"

else

       echo "space"

fi

9. ${ } 用法

${file#*/}:拿掉第一個 / 及其左邊的字串:dir1/dir2/dir3/my.file.txt

${file##*/}:拿掉最後一個 / 及其左邊的字串:my.file.txt

${file#*.}:拿掉第一個 .  及其左邊的字串:file.txt

${file##*.}:拿掉最後一個 .  及其左邊的字串:txt

${file%/*}:拿掉最後一個 / 及其右邊的字串:/dir1/dir2/dir3

${file%%/*}:拿掉第一個 / 及其右邊的字串:(空值)

${file%.*}:拿掉最後一個 .  及其右邊的字串:/dir1/dir2/dir3/my.file

${file%%.*}:拿掉第一個 .  及其右邊的字串:/dir1/dir2/dir3/my

記憶的方法為:

  • # 是去掉左邊(在鍵盤上 # 在 $ 之左邊)

    % 是去掉右邊(在鍵盤上 % 在 $ 之右邊)

    單一符号是最小比對﹔兩個符号是最大比對

${file:0:5}:提取最左邊的 5 個位元組:/dir1

${file:5:5}:提取第 5 個字元右邊的連續 5 個位元組:/dir2

我們也可以對變量值裡的字串作替換:

${file/dir/path}:将第一個 dir 替換為 path:/path1/dir2/dir3/my.file.txt

${file//dir/path}:将全部 dir 替換為path:/path1/path2/path3/my.file.txt

利用 ${ } 還可針對不同的變數狀态指派(沒設定、空值、非空值):

${file-my.file.txt} :假如 $file 沒有設定,則使用 my.file.txt 作傳回值。(空值及非空值時不作處理)

${file:-my.file.txt} :假如 $file 沒有設定或為空值,則使用 my.file.txt 作傳回值。 (非空值時不作處理)

${file+my.file.txt} :假如 $file 設為空值或非空值,均使用 my.file.txt 作傳回值。(沒設定時不作處理)

${file:+my.file.txt} :若 $file 為非空值,則使用 my.file.txt 作傳回值。 (沒設定及空值時不作處理)

${file=my.file.txt} :若 $file 沒設定,則使用 my.file.txt 作傳回值,同時将$file 指派為 my.file.txt 。 (空值及非空值時不作處理)

${file:=my.file.txt} :若 $file 沒設定或為空值,則使用 my.file.txt 作傳回值,同時将 $file 指派為 my.file.txt 。 (非空值時不作處理)

${file?my.file.txt} :若 $file 沒設定,則将 my.file.txt 輸出至 STDERR。 (空值及非空值時不作處理)

${file:?my.file.txt} :若 $file 沒設定或為空值,則将my.file.txt 輸出至 STDERR。 (非空值時不作處理)

tips:

以上的了解在于, 你一定要厘清楚 unset 與 null 及 non-null 這3種指派狀态.

一般而言, : 與 null 有關, 若不帶 : 的話, null 不受影響, 若帶 : 則連null 也受影響.

還有哦,${#var} 可計算出變量值的長度:

${#file} 可得到 27 ,因為/dir1/dir2/dir3/my.file.txt 剛好是 27 個位元組...

10. bash: case 中的 shift 語句是什麼意思?

轉自:http://bbs.chinaunix.net/viewthread.php?tid=218643

這牽扯到 script 或 function 的 positional parameter 。

$0 代表 script 本身(function 的 $0 也是 script)

其後的字串以 IFS 分隔,分別從 $1, $2 ...  起...

[email protected] 或 $* 則是 $1 到最後一個 positional parameter 。

shift 是"參數向左移動",但不好了解...  

我將之說成:shift 就是"砍掉" [email protected]/$* 最左邊的 parameter 。

shift n 則是砍掉 n 個...

比方說,要取得第 10 個 parameter ,可以:

echo ${10}

也可以:

shift 9; echo $1