分类: LINUX
2010-05-31 17:14:35
几个需要记住的特殊参数:
$0 = shell 名称或 shel 脚本名称 $1 = 第一个(1)shell 参数 ... $9 = 第九个(9)shell 参数 $# = 位置参数的个数 "$*" = "$1 $2 $3 $4 ... $n" "$@" = "$1" "$2" "$3" "$4" ... "$n" $? = 最近执行的命令的退出状态 $$ = 当前 shell 脚本的 PID $! = 最近启动的后台作业的 PID
需要记住的基本扩展参数:
形式 如果设置了 var 如果没有设置 var ${var:-string} $var string ${var:+string} string null ${var:=string} $var string (并且执行 var=string) ${var:?string} $var (返回 string 然后退出)
在此,冒号“:”在所有运算表达式中事实上均是可选的。
有“:” = 运算表达式测试“存在”和“非空”。
没有“:” = 运算表达式仅测试“存在”。
需要记住的替换参数:
形式 结果 ${var%suffix} 删除位于 var 结尾的 suffix 最小匹配模式 ${var%%suffix} 删除位于 var 结尾的 suffix 最大匹配模式 ${var#prefix} 删除位于 var 开头的 prefix 最小匹配模式 ${var##prefix} 删除位于 var 开头的 prefix 最大匹配模式
需要记住的基本重定向(redirection)运算符(在此[n]表示定义文件描述符的可选参数):
[n]> file 重定向标准输出(或 n)到 file。 [n]>> file 重定向标准输出(或 n)到 file。 [n]< file 将file重定向到标准输入(或 n)。 [n1]>&n2 重定向标准输出(或 n1) 到n2。 2> file >&2 重定向标准输出和错误输出到 file。 | command 将标准输出通过管道传递给 command。 2>&1 | command 将标准输出或错误输出通过管道传递给 command。
在这里:
stdin: 标准输入 (文件描述符 = 0)
stdout: 标准输出 (文件描述符 = 1)
stderr: 标准错误 (文件描述符 = 2)
shell 允许你通过使用 exec
内嵌一个任意的文件描述符来打开文件。
$ echo Hello >foo $ exec 3bar # 打开文件 $ cat <&3 >&4 # 重定向标准输入到 3,标准输出到 4 $ exec 3<&- 4>&- # 关闭文件 $ cat bar Hello
在这里, n<&- 和 n>&- 表示关闭文件描述符 n。
每条命令均可返回一个退出状态,这个状态值可用于条件表达式:
成功:0 (True)
错误:1–255 (False)
注意该用法,返回值0用来表示“true”与计算机其它领域中常见的转换是不同的。另外`['等阶于使用test
命令进行参数赋值`]'相当于一个条件表达式。
需要记住的常用基本条件表达式:
command && if_success_run_this_command_too || true command || if_not_success_run_this_command_instead if [ conditional_expression ]; then if_success_run_this_command else if_not_success_run_this_command fi
当 shell 使用 -e 调用的时候, 需要使用 || true 来确保这个 shell 不会在本行意外退出。
在条件表达式中使用的文件比较运算符有:
-e file file 存在则返回True。 -d file file 存在且是一个目录则返回 True。 -f file 如果 file 存在且是一个普通文件则返回 True。 -w file 如果 file 存在且可写则返回 True。 -x file 如果 file 存在且可执行则返回 True。 file1 -nt file2 如果 file1 比 file2 新则返回 True。(指修改日期) file1 -ot file2 如果 file1 比 file2 旧则返回 True。(指修改日期) file1 -ef file2 如果两者是相同的设备和具有相同的结点(inode)数则返回 True。
条件表达式中使用的字符串比较运算符有:
-z str 如果 str 长度为零则返回 True。 -n str 如果 str 长度为非零则返回 True。 str1 == str2 如果字符串相等则返回 True。 str1 = str2 如果字符串相等则返回 True。 (使用"=="代替"="符合严格意义上的 POSIX 兼容) str1 != str2 如果字符串不相等则返回 True。 str1 < str2 如果 str1 排在 str2 之前则返回 True(与当前位置有关)。 str1 > str2 如果 str1 排在 str2 之后则返回 True(与当前位置有关)。
条件表达式中的算术整数比较运算符有-eq、-ne、-lt、-le、-gt和-ge。
shell按如下的方式处理脚本:
用这些元字符将其分割成 tokens:SPACE, TAB, NEWLINE, ;, (, ), <, >, |, &
如果不在"..."或'...'内就检查 keyword(循环检查)
如果不在"..."或'...'内就扩展 alias(循环检查)
如果不在"..."或'...'内就扩展 brace,a{1,2} -> a1 a2
如果不在"..."或'...'内就扩展 tilde, ~user -> user's home directory
如果不在'...'内就扩展 parameter, $PARAMETER
如果不在'...'内就扩展 command substitution, $(command)
如果不在"..."或'...'内就用 $IFS 分割成 words
如果不在"..."或'...'内就扩展 pathname *?[]
查找 command
function
built-in
file in $PATH
循环
在双单号内单引号将失效。
在 shell 里执行 set -x 或者使用 -x 选项调用 shell, 该 shell 将会显示出所有执行的命令。 这对调试非常有用。
Make 参考资源:
info make
make(1)
Managing Projects with make, 2nd edition (O'Reilly)
简单自动变量:
语法规则:
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
在此[TAB]代表一个 TAB 符。 在完成 make
变量代换后,shell 将逐行进行解释。在行尾使用 \ 可以续行。使用 $$ 可将 $ 加入到 shell 脚本的环境变量中。
适用于 target 和 prerequisites 的隐含的等价规则:
%: %.c header.h
or,
%.o: %.c header.h
在此,target 包含了 % 字符(确切地说是其中之一),% 可匹配实际的 target 文件名中任何非空子串。prerequisites 同样也使用 % 来显示它们的名字是如何关联到实际的 target 文件名的。
用 Suffix rules 方法来定义 make
的隐含规则(implicit rules)已经过时。GNU make
因为兼容性的考虑仍支持它,但只要有可能就应该使用与之等价的模版规则(pattern rules):
old suffix rule --> new pattern rule .c: --> % : %.c .c.o: --> %.o: %.c
上述规则所使用的自动变量:
foo.o: new1.c new2.c old1.c new3.c $@ == foo.o (target) $< == new1.c (first one) $? == new1.c new2.c new3.c (newer ones) $^ == new1.c new2.c old1.c new3.c (all) $* == `%' matched stem in the target pattern.
变量参考:
foo1 := bar # One-time expansion foo2 = bar # Recursive expansion foo3 += bar # Append SRCS := $(wildcard *.c) OBJS := $(foo:c=o) OBJS := $(foo:%.c=%.o) OBJS := $(patsubst %.c,%.o,$(foo)) DIRS = $(dir directory/filename.ext) # Extracts "directory" $(notdir NAMES...), $(basename NAMES...), $(suffix NAMES...) ...
执行make -p -f/dev/null可查看内部自动规则。
gdb
进行调试准备工作:
# apt-get install gdb
gdb
参考资源:
info gdb (tutorial)
gdb(1)
使用 -g 选项编译程序就可使用 gdb
进行调试。许多命令都可以缩写。Tab 扩展功能和在 shell 中的一样。
$ gdb program (gdb) b 1 # 在line 1 设置断点 (gdb) run arg1 arg2 arg3 # 运行程序 (gdb) next # 下一行 ... (gdb) step # 前进一步 ... (gdb) p parm # 打印 parm ... (gdb) p parm=12 # 设置其值为 12
在 Emacs 环境下调试程序,参阅。
Debian 系统上所有默认安装的二进制文件都已经进行了 strip 操作, 调试符号已经被移除。 为了能够让 gdb
对 Debian 软件包进行调试, 相关的软件包需要使用下面的方法重新打包:
编辑 debian/control
来改变软件包的 。
检查打包脚本,确保使用 CFLAGS=-g-Wall 来编译二进制文件。
设置 DEB_BUILD_OPTIONS=nostrip,noopt 来建立 Debian 包。
更多信息请参阅: 。
使用ldd
可查看程序与库函数的关联关系:
$ ldd /bin/ls librt.so.1 => /lib/librt.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40030000) libpthread.so.0 => /lib/libpthread.so.0 (0x40153000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
可在 chrooted 环境下使用 ls
检查上述库函数在你的 chroot
环境中是否可见。
下面的命令也很有用:
strace
: 跟踪系统调用和消息
ltrace
: 跟踪库函数调用