天天看点

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

可以用退格键,并且显示数字还得按回车键, 从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