显示标签为“Shell”的博文。显示所有博文
显示标签为“Shell”的博文。显示所有博文

2007年8月8日星期三

随时随地进入命令行

呵呵,听起来就像是随地xxoo那么拉风,实际上很简单,写一个注册表文件就行了:
下载: cmd.reg
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\cmd]
[HKEY_CLASSES_ROOT\Directory\shell\cmd\command]
@="cmd /k cd %1"

[HKEY_CLASSES_ROOT\*\shell\cmd]
[HKEY_CLASSES_ROOT\*\shell\cmd\command]
@="cmd /k"

安装方法:点击上面的cmd.reg链接,保存到本地后打开或者直接打开,会提示你是否导入到注册表,选择“是”,然后就ok了。

使用方法:将注册表文件导入以后,随便找个文件或者文件夹右击一下,就可以看到一个”cmd”菜单条目,点击即可进入命令行,而且进入命令行以后自动转入当前目录(即被点击的文件所在目录):

随时随地进入命令行(截图)

怎么样?经常在命令行下工作的用起来还是比较拉风吧。。。

标签:

帮我写一个批处理文件 - 批处理sleep

帮我写一个批处理文件
悬赏分:0 - 解决时间:2007-6-12 11:10
如果c://a.txt文件存在,延迟10秒,复制a.txt从c: 到d:
如果d://a.txt已经存在结束任务
问题补充:大家帮帮忙啊,谢谢大家了
提问者: miss8850 - 助理 三级
最佳答案
@echo off
if exist c:\a.txt (if not exist d:\a.txt (copy c:\a.txt d:\a.txt))

时间你自己想办法加上去 延迟加上去好象不操作了。!

在批处理中实现等待/延迟/暂停(zz)2006年12月29日 星期五 10:55(以下所有的程序均以等待/延迟/暂停2秒示例)
1、比较传统的设计思路,利用for解析变量%time%并存为一个时间点,再利用set计算两个时间点的时间差,最后用if判断时间差是否达到设定的暂停时间。时间精度为0.01秒,适用平台为WinNT/2K/XP/2003。
@echo off
setlocal enableextensions
echo %time%
call :ProcDelay 200
echo %time%
goto :EOF

:ProcDelay delayMSec_
setlocal enableextensions
for /f "tokens=1-4 delims=:. " %%h in ("%time%") do set start_=%%h%%i%%j%%k
:_procwaitloop
for /f "tokens=1-4 delims=:. " %%h in ("%time%") do set now_=%%h%%i%%j%%k
set /a diff_=%now_%-%start_%
if %diff_% LSS %1 goto _procwaitloop
endlocal & goto :EOF

2、使用Windows的VBS脚本中的sleep函数,可以动态创建这个VBS脚本,然后用Windows脚本宿主的命令行版本调用它。时间精度为0.001秒,使用平台为Win9x/WinNT系列。
@echo off & setlocal enableextensions enabledelayedexpansion
echo WScript.Sleep 2000 > %temp%\tmp$$$.vbs
echo %time%
cscript //nologo %temp%\tmp$$$.vbs
echo %time%
for %%f in (%temp%\tmp$$$.vbs) do if exist %%f del %%f
endlocal & goto :EOF

3、如果你的Windows系统中正常安装了网卡的TCP/IP协议,也可以使用ping定时发送测试包,以此达到暂停一定时间的目的;-n后的 数字是发送包的数目,根据植树原则,为暂停秒数加一,此法每秒有0.5%的偏差。时间精度为1秒,使用平台为Win9x/WinNT系列。
ping -n 3 127.0.0.1>nul

4、使用choice的缺省选择等待功能实现暂停,但它有个缺点,就是不能在等待途中按键,否则暂停的倒计时将自动终止。时间精度为1秒,适用平台为MS-DOS/Win9x/WinNT系列。
choice /t:y,2 /n >nul

5、德国人Herbert Kleebauer给出了一个通用方案,通过间接产生一个exe程序来实现延迟,这个程序分为DOS和Win两个模块。延迟精度为0.001秒,适用平台为MS-DOS/Win9x/WinNT。代码见附件

附件:


:: Sleep.bat - Sleep/Delay/Wait n seconds
:: Herbert Kleebauer(Germany) - 2005/05/29
:: Modified by Will Sort - 2005/06/02
@echo off
echo q | debug>nul
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>sleep.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>sleep.com
echo T}{z~~@GwkBG@OEKcUt`~}@MqqBsy?seHB~_Phxr?@zAB`LrPEyoDt@Cj?>>sleep.com
echo pky_jN@QEKpEt@ij?jySjN@REKpEt@jj?jyGjN@SEKkjtlGuNw?p@pjirz>>sleep.com
echo LFvAURQ?OYLTQ@@?~QCoOL~RDU@?aU?@{QOq?@}IKuNWpe~FpeQFwH?Vkk>>sleep.com
echo _GSqoCvH{OjeOSeIQRmA@KnEFB?p??mcjNne~B?M??QhetLBgBPHexh@e=>>sleep.com
echo EsOgwTLbLK?sFU`?LDOD@@K@xO?SUudA?_FKJ@N?KD@?UA??O}HCQOQ??R>>sleep.com
echo _OQOL?CLA?CEU?_FU?UAQ?UBD?LOC?ORO?UOL?UOD?OOI?UgL?LOR@YUO?>>sleep.com
echo dsmSQswDOR[BQAQ?LUA?_L_oUNUScLOOuLOODUO?UOE@OwH?UOQ?DJTSDM>>sleep.com
echo QTqrK@kcmSULkPcLOOuLOOFUO?hwDTqOsTdbnTQrrDsdFTlnBTm`lThKcT>>sleep.com
echo @dmTkRQSoddTT~?K?OCOQp?o??Gds?wOw?PGAtaCHQvNntQv_w?A?it\EH>>sleep.com
echo {zpQpKGk?Jbs?FqokOH{T?jPvP@IQBDFAN?OHROL?Kj??pd~aN?OHROd?G>>sleep.com
echo Q??PGT~B??OC~?ipO?T?~U?p~cUo0x>>sleep.com
sleep.com>sleep.exe
del sleep.com
echo wait 2 seconds:
sleep.exe 2000




其他回答
共 1 条
可以用 ping -n 10 127.1 来延时

@echo off
if exist c:\a.txt ping -n 10 127.1 & if not exist d:\a.txt copy c:\a.txt d:\a.txt






Windows命令行奇技淫巧之 Sleep

作者:兔毛猫 链接:http://www.2maomao.com/blog/windows-tips-sleep-command/

写批处理(Batch)文件的时候,经常会需要在其中等上几秒钟,但是Windows 2000/xp/2003 都没有Sleep命令,怎么办呢?

以前我都是写个Sleep.exe,接受一个毫秒数做参数的,内部调用Sleep win32API。这种做法的坏处是:发布你的批处理文件给别人用的时候,你得把Sleep.exe和批处理文件放在一起。这让本来贴上一段代码就搞定的 活,经常变成需要添个附件(sleep.exe)才能搞定。

今天发现其实很多人有这个困扰,还有一些奇技淫巧在其中:
比如这篇文章提到的方法:

@ping 127.0.0.1 -n 3 -w 1000 > nul

这样就可以不动声色的等待三秒了(不太精准,但是一般也够用了)

再比如这位才子提到的安装Windows Server 2003 Resource Kit Tools的方法,唔,这个比自己写一个sleep.exe强不了多少。

还有这位仁兄的方法:
写一个Sleep.vbs,然后调用它。
其实还可以使用WScript更进简略而且更进一步,直接就Sleep三秒:

@ECHO Wscript.Sleep(3000) > sleep.vbs
@START /w wscript.exe sleep.vbs
@DEL /Q sleep.vbs

孔乙己online睡眼惺忪的问:睡(sleep)姿有108种,你知道吗?



GNU/Linux 指令 read


指令名稱:
read(1) - 讀取標準輸入,作為變數內容(bash shell 內建指令)
語法:
read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]
說明:
read 這個內建指令在交談模式下,極少用到,但在撰寫 shell script 時卻時常少不了她。當 shell scrip 需要與執行者進行"交談"並讀取執行者所鍵入的資料,read 就派上用場了。

指令負責讀取標準輸入的輸入。被讀取的第一個引數指定給第一個變數,第二個引數指定給第二個變數,以下類推。如果對應也所剩餘,則剩餘的引數會全部給最後一個變數。如果對應有所不足,沒有引數對應的變數其內容為空。
選項:
-a aname
讀取標準輸入到指定的陣列變數(aname)。值由 0 開始計算。陣列變數在讀取資料前會自動清空容。
-d delim
用 delim 指定第一個字元(所以需入一個字元即可),來做為結束輸入的字元。
-e
假使標準輸入來自終端機,使用 readline 讀取。
-n nchars
在讀取指定的字元數後,自動結束。
-p prompt
以標準錯誤顯示指定的提示。同時 newline 省略。
-r
關閉符號倒斜線的 escape 定義。
-s
沉默模式,從終端機讀取字元時不回應任何顯示。
-t timeout
設定輸入的時間限制,單位秒。當超過時限未輸入資料,read 將自動終結,執行狀態值為 1。
-u fd
從檔案描述 fd 讀取輸入。
實例說明:
預設的引數與變數對應關係

# cat read00
#!/bin/bash
read -p "S/N: " sn1 sn2 sn3
echo "sn1 $sn1"
echo "sn2 $sn2"
echo "sn3 $sn3"
#

上例是個非常簡單的 script。指令 read 指定了 sn1 sn2 sn3 三個變數來接收標準輸入的引數。以下是執行的情況

# read00
S/N: 00 11 22 33
sn1 00
sn2 11
sn3 22 33

## read00
S/N: 00 11
sn1 00
sn2 11
sn3
#

使用 echo 所輸出的,就是鍵入的引數與 sn1, sn2, sn3 變數的對應結果。這是 read 指令預設的做法。

陣列變數的使用

# cat read-a
#!/bin/bash
read -p "S/N: " -a sn
echo "sn0 ${sn[0]}"
echo "sn1 ${sn[1]}"
echo "sn2 ${sn[2]}"
#

read 指令支援 -a 選項用來宣告陣列變數。上例是,基本的使用與呼叫,以下是執行的情況。

# read-a
S/N: 11 22 33 44
sn0 11
sn1 22
sn2 33
#

設定輸入的時間限制

選項 -t 支援"限時"的功能,這對偷懶或做到一半喜歡亂跑的執行者來說,是個不錯的功能。在下例中,我設定的5秒的時間,一旦超過這個時間沒有輸入,script 會自動終止執行。

# cat read-t
#!/bin/bash
read -p "Any pattern keyin, 5 second, please. :: " -t 5 sn1
if [ "$?" = 1 ]
then
echo "TimeOut, Sorry."
exit 1
fi
echo -n "md5 id: "
echo "$sn1" | md5sum - | colrm 33
exit 0
#

來看看她逾時不候的情況及正常的執行狀態

# read-t
Any pattern keyin, 5 second, please. :: TimeOut, Sorry.
#

# read-t
Any pattern keyin, 5 second, please. :: deke
md5 id: eb2dde2422a2044de4ab8348e147c6f5
#

自訂輸入終止字元

一般情況下,我們都是以 return 來終止資料的輸入。但,如果有一天,我們 return 字元也是資料輸入的一部分時,怎麼辦?

選項 -d 可以幫我們解決這個問題。

# cat read-d
#!/bin/bash
echo "Keyin any number (Type . to end your input.)"
read -d . kk
echo "(end)"
echo $kk
#

上例,我指定符號 . 來做為輸入終止的符號。因此在輸入數字時,使用 return 就不會中斷我的輸入了。這對某些輸入提供了相當的便利性。

# read-d
Keyin any number (Type . to end your input.)
838393
985939
399230
399590
939939.(end)
838393 985939 399230 399590 939939
#

限定輸入字元數

使用 -n 選項,可以讓我們控制輸入的字元數,當輸入到設定的字元數目時,read會自動終結。

# cat read-n
#!/bin/bash
echo "Keyin your ID: "
read -n 9 eu
echo -e "\n\nyour ID: $eu"
#

在 script 撰寫中 read 算是一個相當常用的指令,以上的幾種型態的運用,算是 script 撰寫的基礎。這篇暫時到此。

Bash使用详解

命令补齐相关

  • 在bash中可以通过C-r激活历史记录的增量搜索模式或者用C-\ C-i或 M-\ C-i动态历史完成

常用的快捷键

bash底层采用的GNU的readline库作为底层输入接口的, readline支持两种行输入模式, emacs风格和vi风格, 默认情况下用的时emacs风格. 下面的快捷键都是针对emacs风格, 因为vi风格我很少用.
C-u      删除一行
C-k 删除到行尾
M-# 注释掉当前命令
M-. yank-last-args 将上一个命令的最后一个参数放入当前命令行(可多次使用)
M-! complete-command 补齐命令名
M-$ complete-variable 补齐变量名
complete 自动补齐
M-/ complete-filename 补齐文件名
M-~ complete-username 补齐用户名
M-@ complete-hostname 补齐主机名
M-* insert-completions 通配符扩展
C-x * glob-expand-word 通配符扩展
M-? 列出所有可能的完成
C-x/ 列出所有可能的文件名完成
M- 在历史列表中进行补齐
由于readline的配置文件时INPUTRC环境变量指定,确实时~/.inputrc, 所以我们可以配置该文件的选项适合我们的需要:
 "\c-w"   kill-region
为了使新的绑定生效,执行re-read-init-file函数, 缺省绑定在C-x C-r上.
可以用
$bind -p
显示所有的键绑定.下面是其他一些可以用来查询的工具函数和建议的绑定
dump-functions    查询所有可用的函数   C-xf
dump-variable 查询所有可用的变量 C-xv
dump-macros 查询所有可用的宏 C-xm
下面是一些可用的配置变量:
bell-style        出错的报警方式      audible, visible, none
edit-mode 编辑模式 emacs, vi
completion-query-time
expand-tile 当为on时, 按下键时,~将扩展为用户主目录
visible-stat 为on时, 目录,可执行文件,链接后加/,*,@
设置在~/.inputrc下写入类似的语句:
 set visible-stats on
可以用
$bind -v

显示所有的可设置的参数.
也可以用set命令直接在命令行完成对参数的设置. 例如:
$set -o emacs 或者 $set -o vi  #打开emcs或者vi方式
  • bash中的常用的控制字符及其输入键
    C-M           [return]
    C-? [del]
    C-c intr
    C-d EOF
    C-\ quit (若C-c无效,可用此快捷键终止当前命令)
    C-Q 重新开始屏幕输出
    C-S stop 停止屏幕输出
    C-u/U 删除当前行
    C-z 挂起
    可以用命令stty查看这些信息
    stty -a
    可用help命令得到当前的shell的内置命令的列表.
  • 特殊的符号
    !            #启用历史替换
    !! #引用最后一条命令
    ! n #引用历史记录的第n条命令
    ! -n #引用当前命令行前面n条命令
    !string #引用以string开始的最后一条命令
    ! ?string? #引用包含string的最后一条命令
    ^string1^string2 #恢复最后的命令,并用string2替换string1

编程相关

  • ~a/ 代表用户a的主目录. ~/ 代表当前用户的主目录
  • 在bash中用[ !set ] 匹配不再当前set中的字符, 而不是用[^set]. 这一点在脚本编程时一定要注意
  • shell中资源的优先级: 别名 关键字 函数 内置命令 脚本 可执行程序
  • 取得最后执行的命令的返回值 $?
  • command 是shell的内置命令, 用于屏蔽函数和别名查找的.
  • 当自己定义的函数覆盖掉了shell的内部命令时,可以用buildin执行shell的内部命令.例子如下:
    cd ()
    {
    buildin cd "$@"
    echo "$OLDPWD=>$PWD"
    }

变量

-declare可以用来声明变量
-a       #将变量看成数组
-f #只使用函数名
-F #显示未定义的函数名
-i #将变量看成整数
-r #使变量只读
-X #标记变量为未导出
-x #与export等价, 标记变量为导出
readonly -f #将参数解释为函数名而非变量名
readonly -n #删除该名称的只读属性
readonly -p #用内置命令打印只读名称列表
readonly -a #将名字参数解释为数组
  • 声明数组
  1. 第一种
     names[2]=alice; name[0]=hatter; names[1]=duchess
    names={[2]=alice [0]=hatter [1]=duchess}
    names={ hutter duchess alice}
  2. 第二种
    declare -ar names #声明names为只读数组变量
  3. 数组的一些操作
    ${names[i]}   #引用names的第i个元素, 用"@"和"*"引用所有的数组元素
    ${#names[i]} #引用names的第i个元素的长度
    ${#names[@]} #数组的长度
  4. 用unset可以删除数组的元素甚至整个数组.
  • 特殊的变量
    $$            #当前进程的ID
    $! #最后一个后台作业的进程ID
    $RANDOM #让shell产生一个随即数
    $REPLY #read的读入结果的原始数据

参数

对于0-9的参数可以用$0,...$9来引用, 多余9的参数可以用${10}这种格式来引用.
shift可以用来移动参数

函数

  • 定义
    在bash中支持两种函数定义方式,格式分别如下:
    function functionname
    {
    shell command
    }
    或者
    functionname()
    {
    shell command
    }
    一个例子
    funciotn afunc
    {
    local var1
    echo in funtion
    echo var1
    }
  • 查看
    declare -f     #查看会话中定义的所有的函数
    declare -F #只显示函数的名称
  • 删除
    unset -f funtionname   #删除名为functionname的函数
  • 函数与脚本的区别在于:函数不在单独的子进程中运行, 而脚本在单独的子进程中运行

操作符

  • 替换操作符
    ${vn:-w}   #若vn存在且非null, 返回其值, 否则返回w (返回一个变量的值,如果没有取默认)
    ${vn:=w} #若vn存在且非null, 返回其值, 否则先设置vn为w,然后返回其值(设置默认值)
    ${vn:?w} #若vn存在且非null, 返回其值, 否则打印vn后跟w,然后退出. (用于检查变量的值, 捕捉未定义的变量
    ${vn:+w} #若vn存在且非null, 返回w,否则返回null (测试变量的存在性)
    ${vn:offset} #返回vn从offset喀什常为length的的子串, 基于0索引, 若offset小于0,则由后往前数, 入vn为"@",length则为从offset开始的参数的个数
    ${vn:offset:length}
  • 模式匹配操作符
    ${vn#pattern}         #若pattern匹配vn的开头,删除最短匹配并返回其余部分.
    ${vn##pattern} #若pattern匹配vn的开头,删除最长匹配并返回其余部分.
    ${vn%pattern} #若pattern匹配vn的结尾,删除最短匹配并返回其余部分.
    ${vn%%pattern} #若pattern匹配vn的结尾,删除最长匹配并返回其余部分.
    ${vn/pattern/str} #最长匹配被str替换一次
    ${vn//pattern/str} #最长匹配被str替换所有
    下面时一个匹配的例子
    $ PATH=/home/cam/book/log.file.name
    ${PATH##/*/} => log.file.name
    ${PATH#/*/} => cam/book/log.file.name
    ${PATH%.*} => /home/cam/book/log.file
    ${PATH%%.*} => /home/cam/book/log
  • 其他操作符
    ${#vn} 返回vn的串长,如若filename=alice.c,那么${#filename}=7
    下面是一个利用变量的例子
    vi ${grep -l "define" *.c}  #编辑所有含有define的c的源文件, -l指示grep只打印文件名

条件测试和流程控制

  • 若if和then放在同一行, 那么他们中间必须用";"隔开.下面是一个例子:
    if [ -n "$dirname" ] && [ \( -d "$dirname" \) -a \( -x "$dirname" \) ] ; then
  • 可以用!对测试取反
    if [ -x "$1" -a ! -d "$1" ] ; then
  • select结构 select是一个循环结构, 只能用break跳出,或者通过C-D退出循环
    select name [ in list ]
    do
    command
    done
    例如:
    selectd()
    {
    PS3='directory?'
    select selection in $DIR_STACK ; do
    if [ $selection ] ; then
    ...
    break
    else
    echo 'invaild selector'
    fi
    done
    }

算术运算

  • shell将$((和))包含的单词解释为算术表达式
  • B#N表示B进制数N, B的去值2-36,省略B#默认为10.
  • 也可以用let语句将算术表达式求值并付给相应的变量
    let x='1+4' => $x=5
    let x='1<<4'> $x=16

输入和输出重定向

>1 file        #即使设置了no clobber,仍然强制的将标准输出定向到file
n>1 file #即使设置了no clobber,仍然强制的将文件描述符n定向到file
<>file #file既做标准输出又做标准输入
n<>file #file既做文件描述符n的输出又做其输入
<< label #here-document 见文本
n>& #将标准输出复制成文件描述符n
n<& #将标准输入复制成文件描述符n
n>&m #使文件描述符n成为输出文件描述符m的副本
n<&m #使文件描述符n成为输入文件描述符m的副本
&>file #定向标准输出和标准错误到file
<&- #关闭标准输入
>&- #关闭标准输出
n>&- #关闭描述符n的输出
n<&- #关闭描述符n的输入
read 用于从文件中读取输入, 每次一行, 以"\n"结尾
eval 用与对于一个字符串进行脚本求值

信号与自陷

  • 捕捉信号在shell中可以通过trap内置命令使脚本捕获对信号的处理,格式如下:
    trap cmd sig1 sig2 ...   #意思就是当sig1, sig2, ... 等发生的时候, 执行cmd. 然后再继续脚本的执行. cmd使定义在脚本中的函数, sig#可以使数字,也可以使信号的名称
    下面是一段实例代码
    trap "echo, You hit C-c" INT
    while true ; do
    sleep 60
    done
  • 忽略信号要想忽略掉信号的处理, 用空串代替 cmd即可
    trap "" HUP
    对于HUP信号,也可以用nohup指令, 如下所示:
    [eval] nohup "$@" >logfile 2>&1 &
    nohup是一个外置的Unix命令.
  • 重置信号处理
    trap - sigs ...  #重置sigs信号采用shell的缺省处理方式
  • EXIT信号 EXIT是一个伪信号, 起作用是使得脚本无论以什么方式退出的时候都执行EXIT后面指定的代码
  • DEBUG信号 DEBUG是一个伪信号, 其作用是使得脚本执行完每条语句后都执行DEBUG后面的代码

作业控制

  • disown命令
    disown命令可以让你失去对一个作业的控制权, 以后你就只能通过该作业的进程ID来控制该作业了. diswon -h <> nohup
- wait 内置命令wait可以用来等待作业的完成, 不带参数时等待所有 - 括号用圆括号括起来的一组命令将在子shell中执行 ** <>"sec-13">注意与建议
  • 如果代码包含变量定义和信号陷阱, 除非效率时考虑的关键因素, 否则则应该用zishell代替命令块

代码sample

  1. 利用shift和case处理不带参数的选项
    while [ -n "$( echo $1 | grep '^_' )" ] ; do
    case $1 in
    -a ) process option -a
    ;;
    -b ) process otion -b
    ;;
    * ) echo 'usage: alice [-a] [-b] args ...'
    exit 1
    esac
    shift
    done
  2. 处理带参数的选项
    while [ -n "$( echo $1 | grep '^_' )" ] ; do
    case $1 in
    -a ) process option -a
    ;;
    -b ) process otion -b
    $2 is the option's argument
    shift
    ;;
    * ) echo 'usage: alice [-a] [-b] args ...'
    exit 1
    esac
    shift
    done
  3. 利用getopts处理参数
    shell提哦功能了getopts处理参数, getopts有两个参数, 第一个是半晌字母和冒号的字符串, 每个字母均为有效选项, 如果字母后面有一个冒号,则该选项带一个参数. 第一个":"表示脚本自己处理错误. getopts从命令行中抽取相应的选项, 将其赋值给getopts的第二个参数(不带"-"). 例如:
    while getopts ":ab:c" opt ; do
    case $opt in
    a ) process option -a
    b ) process option -b
    $OPTARG is the option's argument
    ;;
    c ) process option -c
    \? ) echo 'usage : alice [-a] [-b arg] [-c] args'
    exit 1
    ;;
    esac
    done
    shift $(($OPTIND - 1 ))

配置文件

  • .bash_profile
    该文件只被登陆shell读取, 启动的新shell只读取.bashrc文件
  • .bashrc
    该文件被启动的每个shell读取
  • .bash_logout bash退出时执行该文件

bash的调试器选项

set -o         命令选项      行为
noexec -n 不运行命令, 只检查语法错误
verbose -v 在运行命令前回送他们
xtrace -x 在命令处理后回送他们

提示符的定制

  • 特殊字符提示符的定制中可能用到如下的特殊字符串:
    \a        #响铃 (007)
    \d #格式日期(星期,月,日)
    \e #ascii转义字符(003)
    \H #主机名
    \h #主机名加"."
    \n #回车,换行
    \s #shell的名字
    \T #12小时的时间(HH:MM:SS)的当前时间
    \t #24小时的当前世界(HH:MM:SS)
    \a # 12小时的当前时间,(am/pm)
    \u #当前用户的名称
    \v #当前bash的版本
    \V #当前bash的详细版本
    \w #当前工作目录
    \W #全路径的工作目录
    \# #当前命令的编号
    \! #当前命令的历史编号
    \$ #打印$, 若uid=0,打印#
    \nnn #8进制的字符码
    \\ #反斜线
    \[ #开始非打印字符序列
    \] #结束非打印字符序列
  • PS4 PS4时bash的第四个提示符, 用于在xtrace的时候缩进. 如在.bashrc中写入如下的语句,就可以在xtrace的时候看到当前行的编号了.
    PS4='$0line $LINENO'   #LINENO时shell的内置变量,用于记录当前运行的脚本的行编号.

内置命令

  • hash 列出bash命令的hash列表
  • set 设置选项
  • type 查看命令的简短说明
    type -all command      #查看command的所有定义的细节
    type -path command #只对可执行文件和脚本,输出其路径
    type -type command #输出命令的简短描述

环境变量

HISTFILE     #指示当前的bash所用的历史文件
CDPATH #cd命令的搜索路径; "."不用单独设置, 永远包含
HOME #主目录
BASH_VERSINFO #shell版本信息的数组
SECONDS #启动的秒数
PWD #当前的工作目录
BASH #当前运行的shell的实例的路径名
OLDPWD #上一个工作目录
BASH_VERSION #shell的版本号
TERM #终端的类型
COLUMNS #终端的列数
LINES #终端的行数
EDITOR #编辑器
可以为一个命令配置特殊的环境变量
varname=varvalue command
给cmd指定一个名为varname的变量其值时varvalue.
用export [-p] 可以查看所有已导出的环境变量.

其他

  • 更换自己的登录shell
    chsh /usr/local/bin/bash

GNU/Linux 指令 trap

指令名稱:
trap(1) - 信號捕捉 (bash shell 內建指令)
語法:
trap [-lp] [arg] [sigspec ...]
說明:
這 個內建指令的名字取的相當有意思。trap 是"陷阱"的意思,她會捕捉我們所指定的信號(sigspec),當符合指定的信號產生,trap 就會執行使用者交付給她的指令(arg)。通常會使用到 trap 大多是為了debug script。我們可以就由她來了解 script 的執行細節或回報狀態。在交談模式下則幾乎沒有使用她的理由。

當指令的 arg 沒有指令或帶入了 - 符號時,所有信號將會被回復成初始值。當 arg 為空字串,則所有指定的信號將會被 shell 忽略執行帶入的指令。當指令使用 - p 選項同時沒有 arg 指定時,顯示 sigspec 信號的指令。

基本上 sigspec 允野H名稱或數字來代入。EXIT(0) 代表退出 shell 之後執行 arg 命令。DEBUG 代表每個簡單指令(Simple Commands[註1]) 後執行 arg 命令。DEBUG trap 不執行來自於 until 或 while 迴圈,或 if 的判斷式,或 && 及 || 邏輯判斷等執行失敗的命令,還有執行狀態值被反轉時也不予以執行。在交談模式下,使用選項 -l 可以顯示所有的信號名稱及相對應的數值資料。
實例說明:
顯示信號名稱與對應的數值
# trap -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 33) SIGRTMIN 34) SIGRTMIN+1
35) SIGRTMIN+2 36) SIGRTMIN+3 37) SIGRTMIN+4 38) SIGRTMIN+5
39) SIGRTMIN+6 40) SIGRTMIN+7 41) SIGRTMIN+8 42) SIGRTMIN+9
43) SIGRTMIN+10 44) SIGRTMIN+11 45) SIGRTMIN+12 46) SIGRTMIN+13
47) SIGRTMIN+14 48) SIGRTMIN+15 49) SIGRTMAX-14 50) SIGRTMAX-13
51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10 54) SIGRTMAX-9
55) SIGRTMAX-8 56) SIGRTMAX-7 57) SIGRTMAX-6 58) SIGRTMAX-5
59) SIGRTMAX-4 60) SIGRTMAX-3 61) SIGRTMAX-2 62) SIGRTMAX-1
63) SIGRTMAX
#

看起來只是一份簡單的表列...但卻可以讓我們寫的很累....實在讓我越看越感覺敬畏。幸虧羅素他老人家生的早,要不然,肯定活不到 49...

在 script 中的運用

請假設你面對一支數百行的 shell script,在空無一人的辨公室..深夜孤燈下的你在明明不該抽煙的電腦房裡,一口一口地吐出無奈的 X 字煙霧...快咪上眼睛的頭腦中...你告訴自己...豬八戒...豬八戒...怎麼...豬八戒(台語)

這時如果你能善用 trap 來觀察可疑點的執行狀態的話,或許有助於問題的解決。以下是個過度簡化的簡陋例子...實際的運用大概也和以下相去不遠...

# cat trap01
#!/bin/bash
trap 'echo Varible Listing -- aa = $aa , bb = $bb' EXIT
aa=10
bb=21
exit 0
#

第一行的 trap 指令,我設定捕捉 EXIT 信號,用 echo 來顯示當時的變數數值..然後請假設你在屬不清的問題迴圈中插入 exit 0,想知道當時的變數數值....或許善用的巧妙的話...收工就有望了。

以下是上例的執行結果

# trap01
Varible Listing -- aa = 10 , bb = 21
#

或許,永遠用不到這個指令的人是幸福的...這篇暫時簡單到此。

網路農夫 2004/01/16

備註: 這段當作功課好了,讓我偷懶一下....
*1 SHELL GRAMMAR -- Simple Commands
A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator. The first word specifies the command to be executed, and is passed as argument zero. The remaining words are passed as arguments to the invoked command.

The return value of a simple command is its exit status, or 128+n if the command is terminated by signal n.