C=word文字叠加在一起起的特殊符号

扫二维码下载作业帮
2亿+学生的选择
下载作业帮安装包
扫二维码下载作业帮
2亿+学生的选择
图纸上标有一个C和一个L是什么意思?C和L是叠在一起的.
扫二维码下载作业帮
2亿+学生的选择
Central Line 中心线
为您推荐:
其他类似问题
结施平面图上CL表示次梁。C和L叠在一起可能是打印问题,经常拷贝到各电脑里会出现重叠字的情况。
图纸的简称 =_=~
扫描下载二维码新手小心:c语言中强符号与弱符号的使用_C 语言
作者:用户
本文讲的是新手小心:c语言中强符号与弱符号的使用_C 语言,
声明:下面的实例全部在linux下尝试,window下未尝试。有兴趣者可以试一下。文章针c初学者。c语言的强符号和弱符号是c初学者经常容易犯错的地方。而且很多时候,特别是多人配合开发的程序,它引起的问题往往非常行为怪异而且难以定位。什么是
声明:下面的实例全部在linux下尝试,window下未尝试。有兴趣者可以试一下。针c初学者。c语言的强符号和弱符号是c初学者经常容易犯错的地方。而且很多时候,特别是多人配合的程序,它引起的问题往往非常行为怪异而且难以定位。什么是强符号和弱符号?在c语言中,函数和初始化的全局变量是强符号,未初始化的全局变量时弱符号。强符号和弱符号的定义是连接器用来处理多重定义符号的,它的规则是:不允许多个强符号;如果一个强符号和一个弱符号,这选择强符号;如果多个弱符号,则任意选一个。它的陷阱:上代码:
复制代码 代码如下:
//main.c#include &stdio.h&int fun();int main(){ printf("in main.c:x=%p\n", &x); fun(); return 0;}//test.c#include &stdio.h&int fun(){ printf("in test.c:x=%p\n", &x); return 0;}
编译:gcc main.c test.c,运行,结果:in main.c:x=0x80496a8in test.c:x=0x80496a8两个x是一个变量。这也许可以说的过去,可能一个忘记加extern了。再看:
复制代码 代码如下:
//main.c#include &stdio.h&int fun();int main(){ printf("in main.c:&x=%p\n", &x); fun(); return 0;}
复制代码 代码如下:
//test.c#include &stdio.h&struct{&span style="white-space:pre"& &/span&&span style="white-space:pre"& &/span&&span style="white-space:pre"& &/span&&span style="white-space:pre"& &/span&&span style="white-space:pre"& &/span&
复制代码 代码如下:
&span style="white-space:pre"& &/span&
复制代码 代码如下:
}int fun(){ printf("in test.c:&x=%p\n", &x); return 0;}
运行结果:in main.c:&x=0x80496e0in test.c:&x=0x80496e0连接器还认为他们是一个变量,这个时候程序员非常可能认为他们是两个变量(或者说优秀的程序员会)。而事实却相反,同一块内存,在不同的文件中会有不同的类型和含义。这两个文件对这块内存读写的过程中,都会影响到对方,引发非常诡异的问题。设想一下,如果是一个程序同时又多个人员来开发,如果他们只有有一个全局变量重名,且没有初始化,那么就会引发问题了。在一个程序中出现问题还算好,毕竟代码都在一起。如果你使用的动态库或者静态库中有未初始化的全局变量,并且恰好也和你定义的重名,结果如何?我尝试过,和上面一样,冲突的两个变量地址也相同。而这个时候你如果没有库的源码,当发生了问题,变量被修改,你估计要走很多弯路才能想到是库改了你的变量。这是我曾经解决过的一个问题。从那之后,我要求我们公司所有库的源码中不可以出现非static全局变量。如何避免?1、上策:想办法消除全局变量。全局变量会增加程序的耦合性,对他要控制使用。如果能用其他的方法代替最好。2、中策:实在没有办法,那就把全局变量定义为static,它是没有强弱之分的。而且不会和其他的全局符号产生冲突。至于其他文件可能对他的访问,可以封装成函数。把一个模块的数据封装起来是一个好的实践。3、下策:把所有的符号全部都变成强符号。所有的全局变量都初始化,记住,是所有的。如果一个没有初始化,就可能会和其他人产生冲突,尽管别人初始化了。(自己写代码测试一下)。4、必备之策:GCC提供了一个选项,可以检查这类错误:-fno-common。c语言为什么设计它?容易引发问题,怎么回事C的一个特性?可能是历史的原因,没有深究。但我认为也可能是部分语言设计哲学的原因:c语言的设计哲学有一点就是充分的相信程序员,给他们最大的权利和灵活性。这个特性在某些特殊的情况下也许可能发挥作用。语言中的君子和小人:古人说要近君子,远小人。像今天说的这个特性(共同体也可以算一个),应该是c语言中的“小人”(轻拍,可能说的比较重)。我们还是敬而远之的比较好。康熙好像说过,(特殊时期)治国不但要用君子,还要会用小人,但要能够驾驭得当。否则会引火烧身。
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c语言
世界语言、计算机语言、编程语言、预言、语言 英文,以便于您获取更多的相关知识。
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
6款热门基础云产品6个月免费体验;2款产品1年体验;1款产品2年体验
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
开发者常用软件,超百款实用软件一站式提供
云栖社区()为您免费提供相关信息,包括
,所有相关内容均不代表云栖社区的意见!特殊字符高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍前一页下一页3. 特殊字符用在脚本和其他地方的特殊字符#注释. 行首以#(#!是个例外)开头是注释.
1&# This line is a comment.注释也可以放在于本行命令的后边.
1&echo "A comment will follow." # 注释在这里.
^ 注意#前边的空白注释也可以放在本行行首空白的后面.
1& # A tab precedes this comment.命令是不能放在同一行上注释的后边的. 因为没有办法把注释结束掉,
好让同一行上后边的"代码生效".
只能够另起一行来使用下一个命令. 当然, 在echo中转义的#是不能作为注释的.
同样的, #也可以出现在特定的参数替换结构中,
或者是出现在数字常量表达式中.
1&echo "The # here does not begin a comment."
2&echo 'The # here does not begin a comment.'
3&echo The \# here does not begin a comment.
4&echo The # 这里开始一个注释.
6&echo ${PATH#*:}
# 参数替换, 不是一个注释.
7&echo $(( 2#101011 ))
# 数制转换, 不是一个注释.
9&# 感谢, S.C.
标准的引用和转义字符(" ' \)可以用来转义#. 某些特定的模式匹配操作也可以使用#.;命令分隔符[分号, 即;]. 可以在同一行上写两个或两个以上的命令.
1& echo there
4&if [ -x "$filename" ]; then
# 注意: "if"和"then"需要分隔.
echo "File $filename exists."; cp $filename $filename.bak
echo "File $filename not found."; touch $filename
9& echo "File test complete."注意一下";"某些情况下需要转义.;;终止case选项[双分号, 即;;].
1&case "$variable" in
echo "\$variable = abc" ;;
echo "\$variable = xyz" ;;
4&esac."点"命令[句点, 即.]. 等价于source命令(参见 例子 11-21).
这是一个bash的内建命令.."点"作为文件名的一部分. 如果点放在文件名的开头的话, 那么这个文件将会成为"隐藏"文件,
并且ls命令将不会正常的显示出这个文件.
bash$ touch .hidden-file
bash$ ls -l
-rw-r--r--
4034 Jul 18 22:04 data1.addressbook
-rw-r--r--
4602 May 25 13:58 data1.addressbook.bak
-rw-r--r--
877 Dec 17
2000 employment.addressbook
bash$ ls -al
drwxrwxr-x
1024 Aug 29 20:54 ./
drwx------
3072 Aug 29 20:51 ../
-rw-r--r--
4034 Jul 18 22:04 data1.addressbook
-rw-r--r--
4602 May 25 13:58 data1.addressbook.bak
-rw-r--r--
877 Dec 17
2000 employment.addressbook
-rw-rw-r--
0 Aug 29 20:54 .hidden-file
如果作为目录名的话, 一个单独的点代表当前的工作目录,
而两个点表示上一级目录.
/home/bozo/projects
bash$ cd .
/home/bozo/projects
bash$ cd ..
/home/bozo/
点经常会出现在文件移动命令的目的参数(目录)的位置上.
bash$ cp /home/bozo/current_work/junk/* .
."点"字符匹配. 当用作匹配字符的作用时,
通常都是作为正则表达式的一部分来使用,
"点"用来匹配任何的单个字符. "部分引用[双引号, 即"]. "STRING"将会阻止(解释)STRING中大部分特殊的字符.
参见 5.'全引用[单引号, 即']. 'STRING'将会阻止STRING中所有特殊字符的解释.
这是一种比使用"更强烈的形式.
参见 5.,逗号操作符. 逗号操作符链接了一系列的算术操作.
虽然里边所有的内容都被运行了,但只有最后一项被返回.
1&let "t2 = ((a = 9, 15 / 3))"
# Set "a = 9" and "t2 = 15 / 3"
\转义符[反斜线, 即\]. 一种对单字符的引用机制. \X将会"转义"字符X.
这等价于"X", 也等价于'X'.
\通常用来转义"和',
这样双引号和但引号就不会被解释成特殊含义了. 参见 5来深入地了解转义符的详细解释. /文件名路径分隔符[斜线, 即/]. 分隔文件名不同的部分(比如 /home/bozo/projects/Makefile). 也可以用来作为除法算术操作符. `命令替换. `command`结构可以将命令的输出赋值到一个变量中去.
我们在后边的后置引用(backquotes)或后置标记(backticks)中也会讲解.
:空命令[冒号, 即:]. 等价于"NOP" (no op,
一个什么也不干的命令). 也可以被认为与shell的内建命令true作用相同.
":"命令是一个bash的内建命令,
它的退出码(exit status)是"true"(0).
# 0死循环:
operation-1
operation-2
operation-n
9&# 与下边相同:
while true
在if/then中的占位符:
1&if condition
# 什么都不做,引出分支.
take-some-action
在一个二元命令中提供一个占位符, 具体参见例子 8-2,
和默认参数.
1&: ${username=`whoami`}
2&# ${username=`whoami`}
如果没有开头的":"的话, 将会给出一个错误,
除非"username"是一个命令或者内建命令...在here document中提供一个命令所需的占位符.
参见例子 17-10. 使用参数替换来评估字符串变量
(参见例子 9-15).
1&: ${HOSTNAME?} ${USER?} ${MAIL?}
如果一个或多个必要的环境变量没被设置的话,
3&#+ 就打印错误信息.
变量扩展/子串替换. 在与>重定向操作符结合使用时,
将会把一个文件清空, 但是并不会修改这个文件的权限.
如果之前这个文件并不存在, 那么就创建这个文件.
1&: > data.xxx
# 文件"data.xxx"现在被清空了.
3&# 与 cat /dev/null >data.xxx 的作用相同
4&# 然而,这并不会产生一个新的进程, 因为":"是一个内建命令.
参见例子 12-14.在与>>重定向操作符结合使用时,
将不会对预先存在的目标文件(: >> target_file)产生任何影响.
如果这个文件之前并不存在, 那么就创建它. 这只适用于正规文件, 而不适用于管道,
符号连接, 和某些特殊文件. 也可能用来作为注释行, 虽然我们不推荐这么做.
使用#来注释的话, 将关闭剩余行的错误检查,
所以可以在注释行中写任何东西.
然而, 使用:的话将不会这样.
1&: This is a comment that generates an error, ( if [ $x -eq 3] ).
":"还用来在/etc/passwd和$PATH变量中做分隔符.
bash$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
!取反操作符[叹号, 即!]. !操作符将会反转命令的退出码的结果,
(具体参见例子 6-2). 也会反转测试操作符的意义,
比如修改"等号"( = )为"不等号"( != ).
!操作符是Bash的关键字. 在一个不同的上下文中,
!也会出现在变量的间接引用中. 在另一种上下文中, 如命令行模式下,
!还能反转bash的历史机制 (参见Appendix J).
需要注意的是, 在一个脚本中, 历史机制是被禁用的. *通配符[星号, 即*]. *可以用来做文件名匹配(这个东西有个专有名词叫globbing)的"通配符".
含义是, 可以用来匹配给定目录下的任何文件名.
bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh
*也可以用在正则表达式中, 用来匹配任意个数(包含0个)的字符. *算术操作符. 在算术操作符的上下文中, *号表示乘法运算. 如果要做求幂运算, 使用**,
这是求幂操作符. ?测试操作符. 在一个特定的表达式中, ?用来测试一个条件的结果. 在一个双括号结构中,
?就是C语言的三元操作符. 参见例子 9-31.在参数替换表达式中,
?用来测试一个变量是否被set了. .?通配符. ?在通配(globbing)中,
用来做匹配单个字符的"通配符",
在正则表达式中,
也是用来表示一个字符. $变量替换(引用变量的内容).
2&var2=23skidoo
4&echo $var1
5&echo $var2
# 23skidoo
在一个变量前面加上$用来引用这个变量的值. $行结束符. 在正则表达式中,
"$"表示行结束符. ${}参数替换. $*, $@位置参数. $?退出状态码变量. $? 变量
保存了一个命令, 一个函数,
或者是脚本本身的退出状态码. $$进程ID变量. 这个$$ 变量
保存了它所在脚本的进程 ID
[1]()命令组.
1&(a= echo $a)在括号中的命令列表,
将会作为一个子shell来运行.在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的.
父进程, 也就是脚本本身,
将不能够读取在子进程中创建的变量, 也就是在子shell中创建的变量.
2&( a=321; )
4&echo "a = $a"
5&# 在圆括号中a变量, 更像是一个局部变量. 初始化数组.
1&Array=(element1 element2 element3){xxx,yyy,zzz,...}大括号扩展.
1&cat {file1,file2,file3} > combined_file
2&# 把file1, file2, file3连接在一起, 并且重定向到combined_file中.
5&cp file22.{txt,backup}
6&# 拷贝"file22.txt"到"file22.backup"中一个命令可能会对大括号
中的以逗号分割的文件列表起作用.
(通配(globbing))将对大括号中的文件名做扩展. 在大括号中, 不允许有空白, 除非这个空白被引用或转义. echo {file1,file2}\ :{\ A," B",' C'}file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C{}代码块[大括号, 即{}]. 又被称为内部组,
这个结构事实上创建了一个匿名函数(一个没有名字的函数).
然而, 与"标准"函数不同的是,
在其中声明的变量,对于脚本其他部分的代码来说还是可见的.
bash: local: can only be used in a
2&{ a=321; }
3&echo "a = $a"
(说明在代码块中对变量a所作的修改, 影响了外边的变量)
5&# 感谢, S.C.下边的代码展示了在大括号结构中代码的I/O 重定向. 例子 3-1. 代码块和I/O重定向
1&#!/bin/bash
2&# 从/etc/fstab中读行.
4&File=/etc/fstab
7&read line1
8&read line2
9&} < $File
11&echo "First line in $File is:"
12&echo "$line1"
14&echo "Second line in $File is:"
15&echo "$line2"
19&# 现在, 你怎么分析每行的分割域?
20&# 小提示: 使用awk.例子 3-2. 将一个代码块的结果保存到文件
1&#!/bin/bash
2&# rpm-check.sh
4&# 这个脚本的目的是为了描述, 列表, 和确定是否可以安装一个rpm包.
5&# 在一个文件中保存输出.
7&# 这个脚本使用一个代码块来展示.
9&SUCCESS=0
10&E_NOARGS=65
12&if [ -z "$1" ]
echo "Usage: `basename $0` rpm-file"
exit $E_NOARGS
echo "Archive Description:"
rpm -qpi $1
# 查询说明.
echo "Archive Listing:"
rpm -qpl $1
# 查询列表.
rpm -i --test $1
# 查询rpm包是否可以被安装.
if [ "$?" -eq $SUCCESS ]
echo "$1 can be installed."
echo "$1 cannot be installed."
34&} > "$1.test"
# 把代码块中的所有输出都重定向到文件中.
36&echo "Results of rpm test in file $1.test"
38&# 查看rpm的man页来查看rpm的选项.
40&exit 0与上面所讲到的()中的命令组不同的是,
{大括号}中的代码块将不会开启一个新的子shell.
{} \;路径名. 一般都在find命令中使用.
这不是一个shell内建命令. ";"用来结束find命令序列的-exec选项.
它需要被保护以防止被shell所解释. [ ]条件测试. 条件测试表达式放在[ ]中.
值得注意的是[是shell内建test命令的一部分,
并不是/usr/bin/test中的外部命令的一个链接.[[ ]]测试. 测试表达式放在[[ ]]中. (shell关键字). 具体参见关于[[ ... ]]结构的讨论.[ ]数组元素. 在一个array结构的上下文中,
中括号用来引用数组中每个元素的编号.
1&Array[1]=slot_1
2&echo ${Array[1]}[ ]字符范围. 用作正则表达式的一部分,
方括号描述一个匹配的字符范围. (( ))整数扩展. 扩展并计算在(( ))中的整数表达式. 请参考关于(( ... )) 结构的讨论.> &> >& >> < <>重定向.
scriptname >filename
重定向scriptname的输出到文件filename中.
如果filename存在的话, 那么将会被覆盖.
command &>filename
重定向command的stdout和stderr到filename中. command >&2 重定向command的stdout到stderr中. scriptname >>filename
把scriptname的输出追加到文件filename中.
如果filename不存在的话,
将会被创建. [i]<>filename
打开文件filename用来读写,
并且分配文件描述符i给这个文件.
如果filename不存在, 这个文件将会被创建. 进程替换. (command)><(command)在一种不同的上下文中,
"<"和">"可用来做
字符串比较操作. 在另一种上下文中,
"<"和">"可用来做
整数比较操作.
参见例子 12-9. <<用在here document中的重定向. <<<用在here string中的重定向. <, >ASCII
comparison.
1&veg1=carrots
2&veg2=tomatoes
4&if [[ "$veg1" < "$veg2" ]]
echo "Although $veg1 precede $veg2 in the dictionary,"
echo "this implies nothing about my culinary preferences."
echo "What kind of dictionary are you using, anyhow?"
10&fi\<, \>
正则表达式中的单词边界
. bash$ grep '\<the\>' textfile|管道. 分析前边命令的输出,
并将输出作为后边命令的输入.
这是一种产生命令链的好方法.
1&echo ls -l | sh
传递"echo ls -l"的输出到shell中,
3&#+ 与一个简单的"ls -l"结果相同.
6&cat *.lst | sort | uniq
7&# 合并和排序所有的".lst"文件, 然后删除所有重复的行.
管道是进程间通讯的一个典型办法,
将一个进程的stdout放到另一个进程的stdin中.
标准的方法是将一个一般命令的输出,
比如cat或者echo, 传递到一个
"过滤命令"(在这个过滤命令中将处理输入)中, 然后得到结果.
cat $filename1 $filename2 | grep $search_word
当然输出的命令也可以传递到脚本中.
1&#!/bin/bash
2&# uppercase.sh : 修改输入, 全部转换为大写.
4&tr 'a-z' 'A-Z'
字符范围必须被""引用起来
6&#+ 来阻止产生单字符的文件名.
现在让我们输送ls -l的输出到一个脚本中.
bash$ ls -l | ./uppercase.sh
-RW-RW-R--
7 19:49 1.TXT
-RW-RW-R--
109 APR 14 16:48 2.TXT
-RW-R--R--
725 APR 20 20:56 DATA-FILE
管道中的每个进程的stdout比须被下一个进程作为stdin来读入.
否则, 数据流会阻塞,
并且管道将产生一些非预期的行为.
1&cat file1 file2 | ls -l | sort
2&# 从"cat file1 file2"中的输出并没出现.
作为子进程的运行的管道,
不能够改变脚本的变量.
1&variable="initial_value"
2&echo "new_value" | read variable
3&echo "variable = $variable"
# variable = initial_value
如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止.
这种行为被叫做broken pipe,
并且这种状态下将发送一个SIGPIPE 信号.>|强制重定向(即使设置了noclobber选项
-- 就是-C选项). 这将强制的覆盖一个现存文件. ||或-逻辑操作. 在一个条件测试结构中,
如果条件测试结构两边中的任意一边结果为true的话,
||操作就会返回0(代表执行成功).
&后台运行命令. 一个命令后边跟一个&
表示在后台运行.
bash$ sleep 10 &
在一个脚本中,命令和循环都可能运行在后台. 例子 3-3. 在后台运行一个循环
1&#!/bin/bash
2&# background-loop.sh
4&for i in 1 2 3 4 5 6 7 8 9 10
# 第一个循环.
echo -n "$i "
7&done & # 在后台运行这个循环.
# 在第2个循环之后, 将在某些时候执行.
# 这个'echo'某些时候将不会显示.
12&for i in 11 12 13 14 15 16 17 18 19 20
# 第二个循环.
echo -n "$i "
# 这个'echo'某些时候将不会显示.
19&# ======================================================
21&# 期望的输出应该是:
22&# 1 2 3 4 5 6 7 8 9 10
23&# 11 12 13 14 15 16 17 18 19 20
25&# 然而实际的结果有可能是:
26&# 11 12 13 14 15 16 17 18 19 20
27&# 1 2 3 4 5 6 7 8 9 10 bozo $
28&# (第2个'echo'没执行, 为什么?)
30&# 也可能是:
31&# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
32&# (第1个'echo'没执行, 为什么?)
34&# 非常少见的执行结果, 也有可能是:
35&# 11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20
36&# 前台的循环先于后台的执行.
Nasimuddin Ansari 建议加一句 sleep 1
41&#+ 在6行和14行的 echo -n "$i" 之后加这句.
42&#+ 为了真正的乐趣.在一个脚本内后台运行一个命令,有可能造成这个脚本的挂起,等待一个按键
响应. 幸运的是, 我们有针对这个问题的解决办法. &&与-逻辑操作. 在一个条件测试结构中,
只有在条件测试结构的两边结果都为true的时候,
&&操作才会返回0(代表sucess).
-选项, 前缀. 在所有的命令内如果想使用选项参数的话,前边都要加上"-". COMMAND -[Option1][Option2][...]ls -alsort -dfu $filenameset -- $variable
1&if [ $file1 -ot $file2 ]
echo "File $file1 is older than $file2."
6&if [ "$a" -eq "$b" ]
echo "$a is equal to $b."
11&if [ "$c" -eq 24 -a "$d" -eq 47 ]
echo "$c equals 24 and $d equals 47."
-用于重定向stdin或stdout[破折号, 即-].
1&(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
2&# 从一个目录移动整个目录树到另一个目录
3&# [感谢Alan Cox <a.cox@swansea.ac.uk>, 走出了部分修改]
5&# 1) cd /source/directory
6&# 2) &&
"与列表": 如果'cd'命令成功了, 那么就执行下边的命令.
7&# 3) tar cf - .
'c'创建一个新文档, 'f'后边跟'-'指定目标文件作为stdout
'-'后边的'f'(file)选项, 指明作为stdout的目标文件.
并且在当前目录('.')执行.
11&# 5) ( ... )
一个子shell
12&# 6) cd /dest/directory
改变当前目录到目标目录.
13&# 7) &&
"与列表", 同上
14&# 8) tar xpvf -
'x'解档, 'p'保证所有权和文件属性,
'v'发完整消息到stdout,
'f'后边跟'-',从stdin读取数据.
注意:'x' 是一个命令, 'p', 'v', 'f' 是选项.
19&# Whew!
23&# 更优雅的写法应该是:
cd source/directory
tar cf - . | (cd ../dest/ tar xpvf -)
当然也可以这么写:
28&# cp -a /source/directory/* /dest/directory
30&# cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
如果在/source/directory中有隐藏文件的话.
1&bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
--未解压的tar文件--
| --然后把它传递到"tar"中--
如果 "tar" 没能够正常的处理"bunzip2",
4&#+ 这就需要使用管道来执行2个单独的步骤来完成它.
这个练习的目的是解档"bzipped"的kernel源文件.注意, 在这个上下文中"-"本身并不是一个Bash操作,
而是一个可以被特定的UNIX工具识别的选项,
这些特定的UNIX工具特指那些可以写输出到stdout的工具,
比如tar, cat, 等等.
bash$ echo "whatever" | cat -
在需要一个文件名的位置,
-重定向输出到stdout(有时候会在tar和cf中出现),
或者从stdin接受输入, 而不是从一个文件中接受输入.
这是在管道中使用文件导向(file-oriented)工具来作为过滤器的一种方法.
bash$ file
Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file...
在命令行上单独给出一个file, 会给出一个错误信息.
添加一个"-"将得到一个更有用的结果.
这会使shell等待用户输入.
bash$ file -
standard input:
ASCII text
bash$ file -
#!/bin/bash
standard input:
Bourne-Again shell script text executable
现在命令从stdin中接受了输入, 并分析它.
"-"可以被用来将stdout通过管道传递到其他命令中.
这样就允许使用在一个文件开头添加几行的技巧. 使用diff命令来和另一个文件的某一段进行比较: grep Linux file1 | diff file2 -最后, 来展示一个使用-的tar命令的一个真实的例子.例子 3-4. 备份最后一天所有修改的文件
1&#!/bin/bash
在一个"tarball"中(经过tar和gzip处理过的文件)
4&#+ 备份最后24小时当前目录下d所有修改的文件.
6&BACKUPFILE=backup-$(date +%m-%d-%Y)
在备份文件中嵌入时间.
Thanks, Joshua Tschida, for the idea.
9&archive=${1:-$BACKUPFILE}
如果在命令行中没有指定备份文件的文件名,
11&#+ 那么将默认使用"backup-MM-DD-YYYY.tar.gz".
13&tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
14&gzip $archive.tar
15&echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
Stephane Chazelas指出上边代码,
19&#+ 如果在发现太多的文件的时候, 或者是如果文件
20&#+ 名包括空格的时候, 将执行失败.
22&# Stephane Chazelas建议使用下边的两种代码之一:
23&# -------------------------------------------------------------------
find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
使用gnu版本的"find".
find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
对于其他风格的UNIX便于移植, 但是比较慢.
30&# -------------------------------------------------------------------
33&exit 0以"-"开头的文件名在使用"-"作为重定向操作符的时候,
可能会产生问题. 应该写一个脚本来检查这个问题, 并给这个文件加上合适的前缀.
比如: ./-FILENAME,
$PWD/-FILENAME, 或者
$PATHNAME/-FILENAME. 如果变量以-开头进行命名, 可能也会引起问题.
1&var="-n"
2&echo $var
3&# 具有"echo -n"的效果了,这样什么都不会输出的.
-先前的工作目录. cd -将会回到先前的工作目录.
它使用了$OLDPWD 环境变量.不要混淆这里所使用的"-"和先前我们所讨论的"-"重定向操作符.
对于"-"的具体解释只能依赖于具体的上下文.
-减号. 减号属于算术操作. =等号. 赋值操作
# 28在另一种上下文环境中,
"="也用来做字符串比较操作. +加号. 加法算术操作. 在另一种上下文环境中,
+也是一种正则表达式操作. +选项. 一个命令或者过滤器的选项标记. 某些命令内建命令使用+来打开特定的选项,
用-来禁用这些特定的选项. %取模. 取模(一次除法的余数)算术操作. 在不同的上下文中,
%也是一种模式匹配操作. ~home目录[波浪号, 即~]. 相当于$HOME内部变量.
~bozo是bozo的home目录,
并且ls ~bozo将列出其中的内容.
~/就是当前用户的home目录,
并且ls ~/将列出其中的内容.
bash$ echo ~bozo
/home/bozo
bash$ echo ~
/home/bozo
bash$ echo ~/
/home/bozo/
bash$ echo ~:
/home/bozo:
bash$ echo ~nonexistent-user
~nonexistent-user
~+当前工作目录. 相当于$PWD内部变量. ~-先前的工作目录. 相当于$OLDPWD内部变量. =~正则表达式匹配. 这个操作将会在version 3版本的Bash部分进行讲解. ^行首. 在正则表达式中,
"^"表示定位到文本行的行首. 控制字符修改终端或文本显示的行为. . 控制字符以CONTROL
+ key这种方式进行组合(同时按下).
控制字符也可以使用8进制或16进制表示法来进行表示,
但是前边必须要加上转义符. 控制字符在脚本中不能正常使用. Ctl-B退格(非破坏性的), 就是退格但是不删掉前面的字符.Ctl-Cbreak. 终结一个前台作业.Ctl-D从一个shell中登出(与exit很相像). "EOF"(文件结束).
这也能从stdin中终止输入. 在console或者在xterm窗口中输入的时候,
Ctl-D将删除光标下字符.
当没有字符时, Ctl-D将退出当前会话,
在一个xterm窗口中, 则会产生关闭此窗口的效果. Ctl-G"哔" (beep). 在一些老式的打字机终端上, 它会响一下铃. Ctl-H"退格"(破坏性的), 就是在退格之后, 还要删掉前边的字符.
1&#!/bin/bash
2&# Embedding Ctl-H in a string.
4&a="^H^H"
# 两个 Ctl-H's (backspaces).
5&echo "abcdef"
6&echo -n "abcdef$a "
Space at end
^ 两次退格.
8&echo -n "abcdef$a"
结尾没有空格
没有 backspace 的效果了(why?).
# 结果并不像期望的那样.
Ctl-I水平制表符.Ctl-J重起一行(换一行并到行首). 在脚本中, 也可以使用8进制表示法
-- '\012' 或者16进制表示法 -- '\x0a' 来表示. Ctl-K垂直制表符.当在console或者xterm窗口中输入文本时,
Ctl-K将会删除从光标所在处到行为的全部字符.
在脚本中, Ctl-K的行为有些不同,
具体请参见下边的Lee Maschmeyer的例子程序. Ctl-L清屏(清除终端的屏幕显示). 在终端中,
与clear命令的效果相同.
当发送到打印机上时, Ctl-L会让打印机将打印纸卷到最后. Ctl-M回车.
1&#!/bin/bash
2&# Thank you, Lee Maschmeyer, for this example.
4&read -n 1 -s -p $'Control-M leaves cursor at beginning of this line. Press Enter. \x0d'
# 当然, '0d'就是二进制的回车.
6&echo >&2
'-s'参数使得任何输入都不将回显出来.
#+ 所以, 明确的重起一行是必要的.
9&read -n 1 -s -p $'Control-J leaves cursor on next line. \x0a'
'0a' 等价于Control-J, 换行.
11&echo >&2
15&read -n 1 -s -p $'And Control-K\x0bgoes straight down.'
16&echo >&2
Control-K 是垂直制表符.
18&# 关于垂直制表符效果的一个更好的例子见下边:
20&var=$'\x0aThis is the bottom line\x0bThis is the top line\x0a'
21&echo "$var"
这句与上边的例子使用的是同样的办法, 然而:
23&echo "$var" | col
这将造成垂直制表符右边的部分比左边部分高.
这也解释了为什么我们要在行首和行尾加上一个换行符 --
26&#+ 这样可以避免屏幕显示混乱.
28&# Lee Maschmeyer的解释:
29&# --------------------------
在这里[第一个垂直制表符的例子中] . . .
31&#+ 这个垂直制表符使得还没回车就直接打印下来.
这只能在那些不能"后退"的设备中才行,
33&#+ 比如说Linux的console.
垂直制表符的真正意义是向上移, 而不是向下.
它可以用来让打印机打印上标.
col工具可以模拟垂直制表符的正确行为.
Ctl-Q恢复(XON).在一个终端中恢复stdin. Ctl-S挂起(XOFF).在一个终端中冻结stdin.
(使用Ctl-Q可以恢复输入.)Ctl-U删除光标到行首的所有字符.
在某些设置下,
不管光标的所在位置Ctl-U都将删除整行输入. Ctl-V当输入字符时, Ctl-V允许插入控制字符.
比如, 下边的两个例子是等价的:
1&echo -e '\x0a'
2&echo <Ctl-V><Ctl-J>Ctl-V主要用于文本编辑. Ctl-W当在控制台或一个xterm窗口敲入文本时,
Ctl-W将会删除当前光标到左边最近一个空格间的全部字符.
在某些设置下,
Ctl-W将会删除当前光标到左边第一个非字母或数字之间的全部字符. Ctl-Z暂停前台作业.空白用来分隔函数, 命令或变量. . 空白包含空格,
空行, 或者是它们之间任意的组合体.
在某些上下文中,
比如变量赋值,
空白是不被允许的, 会产生语法错误. 空行不会影响脚本的行为, 因此使用空行可以很好的划分独立的函数段以增加可读性. 特殊变量$IFS用来做一些输入命令的分隔符, 默认情况下是空白. 如果想在字符串或变量中使用空白,
那么应该使用引用.注意事项[1]PID,
或进程 ID, 是分配给运行进程的一个数字.
要想察看所有运行进程的PID可以使用ps命令. [2]The shell does the brace
expansion. The command itself acts upon the
result of the expansion.[3]例外: 在pipe中的一个大括号中的代码段可能运行在一个
子shell中.
1&ls | { }
错误. 在大括号中的代码段, 将运行到子shell中,
3&#+ 所以"ls"的输出将不能传递到代码块中.
4&echo "First line is $ second line is $secondline"
# 不能工作.
6&# 感谢, S.C.[4]一个换行符("重起一行")也被认为是空白符.
这也就解释了为什么一个只包含换行符的空行也被认为是空白. 前一页首页下一页基本上一级变量和参数的介绍

我要回帖

更多关于 怎么把图片叠加在一起 的文章

 

随机推荐