We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
loginshell=yes
if [ -n "$loginshell" ]
if [ -n "$loginshell" ] then #登录shell的相关设置 fi
files=$(ls -t /etc/motd ~/.hushlogin ) newerFile=$(echo $files|cut -d " " -f1) if[ $newerFile == /etc/motd ] then cat /etc/motd touch ~/.hushlogin fi unset files unset newerFile
在C shell中有一个名为.logout的设置文件. 当用户退出时.logout中的命令被执行. 但是Bourne 和Korn shell中都没有退出文件. 可以使用一下方式模拟
trap '. ~/.sh_logout;exit' 0
可以通过设置ignoreeof这个shell变量来解决问题:
对于C shell执行
set ignoreeof
对于bash或ksh使用
set -o ignoreeof
echo "something error" 1>&2
在命令前输入command即可以禁止shell函数查找
cd () { command cd "$@" # 这里只会执行命令shell而不会执行cd函数 setvars }
在命令前输入builtin
builtin echo -n "this should be the builtin command echo" # 使用内置命令echo
只需要给出外部命令的全路径即可.
/bin/echo hi # 明确指明使用哪个外部命令
或者也可以使用enable -n将某个/某几个内置bash命令无效化. enable的影响将一直持续到用户退出shell为止.
enable -n echo ls # 禁用内置命令echo和ls enable ls # 重新启动内置命令ls enable -a # 列出所有bash内置命令的状态
可以在EOF标识前放一个反斜杠
# 下面命令会显示$PATH cat <<\EOF $PATH EOF # 下面命令会显示$PATH的值 cat <<EOF $PATH EOF
通配符匹配只对已经存在的文件名作扩展.
而{}模式,则可以对任意文本进行扩展,{}的用法为{扩展1,扩展2,扩展3…}. 例如
cp filename{,.bak} # 相当于 cp filename filename.bak vi /tmp/file{a,b,c,d,e} # 相当于 vi /tmp/filea /tmp/fileb /tmp/filec /tmp/filed /tmp/filee
其中pattern采取的是通配符模式,而不是正则表达式. 例如
var=/home/tmp/work/file.a.el则 echo ${var#/*/} # tmp/work/file.a.el echo ${var##/*/} # file.a.el echo ${var%.*} # /home/tmp/work/file.a echo ${var%%.*} # /home/tmp/work/file echo ${var%/*} # /home/tmp/work可以用于取出目录值
bash中的<(process)被用来执行process并将输出送到一个命令的命名管道中.
可以把它想象成一个文件名参数,文件的内容就是process执行的结果.
若使用的shell没有这个功能,可以用一个shell脚本来代替,该脚本执行一个命令,并将其输出保持到一个临时文件中,然后将临时文件名放到它的标准输出中.
p() { eval "$@" >tmp.$$ 2>&1 echo tmp.$$ }
ksh和bash中,设置变量HISTSIZE的值即可
使用history [N]列出所有/后N个命令
!N
``` sh ls /tmp echo !$ # 等于 echo /tmp ```
输出的结果为如何将file1变成file2的过程,描述使用了ed的命令说明(c为修改行,d为删除行,a为添加行)
可以使用-e选项来输出供ex/ed使用的脚本
输出的结果为如何将file2和file3变成file1的过程,描述使用了ed的命令说明(c为修改行,d为删除行,a为添加行)
diff的输出大量使用了ed的命令来说明,难以理解,可以使用ediff,它会将说明翻译为英文
file1和file2必须是已经排过序的
comm命令显示三列信息
要想不显示那一列的信息,使用-N选项即刻.
正常情况下,后台运行的作业也会把输出输出到用户的屏幕上,这样容易搞乱屏幕. 可以使用stty tostop命令来让试图对终端写入的后台作业停止运行.
若后台作业因为输出到终端而停止,则shell会打印出一条信息:\+ stopped (tty output) somejob
\+ stopped (tty output) somejob
%1表示第1号作业.
%vi表示匹配以vi开头的命令行的作业
%?fn表示命令行中包含fn的作业
``` sh fg %2 # 等于 %2 ```
``` sh bg %2 # 等于 %2 & ```
默认情况下,只有命令的表示输出才回发送到管道中,若要仅将标准错误发送給管道可以使用subshell. 如下所示
(command1 >/dev/null) 2>&1 |command2
或者使用如下方式交换stderr和stdout
command1 3>&2 2>&1 1>&3 |command2
在bash/ksh中设置set -o noclobber后,则shell将不允许IO重定向破坏一个已经存在的文件. 除非在重定向的符号之后添加一个!来显式的通知他.
set -o noclobber
set -o noclobber ls # filea fileb ls >filea # bash: filea: Cannot clobber existing file ls >|filea # 没问题,filea被覆盖了
(cat filea1;echo .bp;cat file2) |nroff (date;who;ls) >log
{ date who ls } > log
使用{}列表与sushell的不同在与,{}的所有操作都是基于当前shell来操作的.
若希望一个程序的输出重定向到一个文件的同时也在屏幕上输出,则可以使用tee命令.
tee命令会将它的标准输入写入到一个文件中,并将相同的文本写入到他的标准输出中.它的格式为:tee [-a] file
ls |tee ls.log # 将ls的结果保存到ls.log中,同时输出到屏幕上 ls |tee -a ls.log # tee -a的意思是将结果添加到ls.log中
&- 关闭标准输出
匹配0个或1个abc
匹配0个或多个abc
匹配1个或多个abc
匹配不包含abc的任何字符串
使用tar打包目录到标准输出|从标准输出tar解包
tar cf - . | (cd ~/backup && tar xBf -) # 需要注意,这里tar -cf不能加参数v,因为有些tar命令的v选项会使得详细输出输出到标准输出而不是标准错误中,从而破坏tar的流
tar的X标志后接一个文件,文件的内容就是排除打包的文件路径列表
echo *~ >/tmp/ExcludeTar tar -cvf e.tar -X /tmp/ExcludeTar . # 排除所有以~结尾的文件 tar -xvf e.tar -X /tmp/ExcludeTar # 解包时排除所有以~结尾的文件
使用-C标识,可以指定tar在打包前先进入指定目录,然后就可以指定相对路径打包了
cd tar -cvf t.tar dir1 -C /tmp/dir2 . # 打包的内容包括~/dir1 /tmp/dir2的内容, tar -tvf t.tar # 但路径都为./
这是因为,tar实际上是为磁带归档所设计的. 它会在每个文件的末尾加上垃圾空字符以沾满一个块的空间,因此实际上一个大的tar文件和里面单独小文件所占用的磁盘块差不多.
但是可以通过对tar包进行压缩的方式来解决这个问题,因为大量的空字符实际上非常适用于压缩算法.
find . -atime +5 \( -name "*.o" -o -name "*.tmp" \) -print # 这里的要用\(\),因为()是subshell的操作符
find . -exec myTest {} \; -print # 只有通过myTest的文件才会输出
find. -type d -exec mkdir /usr/project/{} \; # 这里的{}不会被扩展 # 需要改为 find . -type d -print |sed 's@^@/usr/project/@' |xargs mkdir # 先用sed转换,再传给mkdir来创建目录
``` sh ls -i find . -inum 9620 -exec rm {} \; find . -inum 9620 -exec mv {} ordinaryname \; ```
find . \( -type d -a -exec chmod 771 {} \; \) -o \ \( -name "*.BAK" -a -exec chmod 600 {} \; \) -o \ \( -name "*.sh" -a -exec chmod 755 {} \; \) -o \ \( -name "*.txt" -a -exec chmod 644 {} \; \) -o \
创建find数据库
cd find . -print |sed "s@^./@@" > ~/.fastfinddb # 存储~/下的所有文件信息,并替换到./
创建cron定时运行该脚本.
创建一个shell脚本来使用这个数据库
ffind() { egrep "$1" ~/.fastfinddb |sed "s@^@$HOME/@" # 在查询结果前添加$HOME }
ln f1 f2 f3 /tmp # 在/tmp下创建名为f1 f2 f3的链接
cd /tmp ln ~/bin/file # 在/tmp创建一个名为file的链接,链接到~/bin/file下
expr arg1 operator arg2 [operator arg3…]
如果表达式的值非0并且非空,那么expr的退出状态值为0;如果表达式的值为0或者空,则退出状态值为1;如果表达式无效,则退出状态值为2
``` sh expr \( 5 + 10 \) / 2 # 7 ```
大于
= 大于等于
``` sh p="version.100" expr "$p" : '.*' # 11 expr "$p" : '\(.*\)' # "version.100" ```
echo "scale=2;10/4"|bc # 结果为2.50
需要注意的是,若先设置ibase=N,再设置obase=M时,M已经是以N进制来计算了,例如
echo "ibase=8;obase=16;17" |bc # 结果为11
之所以结果为11是因为obase的16使用的是8进制,它的值其实是14
yes会不断重复地输出它的参数(默认为y),使用它和head命令一起可以生成任意长度大小的文件. 例如
要生成每行8个字符(7个数字和一个换行符),共12800行的文件,则输入
yes 1234567 |head -12800 >file
cd (){ test -r .exit.sh && . .exit.sh builtin cd "$1" test -r .enter.sh &&. .enter.sh }
vgrep() { case $# in 0|1) echo "Usage: `basename $0` pattern file [files...]" 1>&2 ;; *) pattern = $1 shift grep -c $pattern "$@" |sed -n 's/:0$//p' ;; esac }
change time是对文件的inode进行修改,比如文件名,权限等
modification time是对文件的内容进行修改
但若是跨文件系统移动文件,那么被移动的文件的所有者将改为你.
这时因为,在跨文件系统移动时,mv实际上必须拷贝该文件,并删除原文件
一般情况下,若一个用户又对某目录的写权限,则它可以对该目录中的文件进行重命名或者删除操作–即使文件并不属于该用户.
通过设置目录的sticky位(1000)可以使得只有文件的所有者,目录的所有者和超级用户才能对文件进行重命名或删除.
chmod 1777 ~/tmp chmod +t ~/tmp ls -l ~/tmp # /tmp的属性显示为drwxrwxrwt,最后的t标识sticky位
终端的标准输出被映射成了/dev/中的tty文件了,而clear清除屏幕的方法是通过TERMINFO查询终端的清除键序列,然后输出该键序列到标准输出中.
因此,若终端类型一致,且用户具有对/dev/tty文件的写权限的化,可以通过clear>/dev/tty来实现清空其他终端上内容
who |grep darksun # darksun pts/6 9月24 20时2 (10.8.201.68) clear >/dev/pts/6 # 清空/dev/pts/6的屏幕显示
假设某个进程会不断的写日志到~/logfile中,而该日志并无用处,则可以
ln /dev/null ~/logfile
通过修改/etc/magic能够增加可识别的文件类型
/etc/magic有四个字段:
offset data-type value file-type
文件中的偏移量,从0开始计算. 表示file从该偏移量开始匹配
测试类型. 文本比较用string,字节比较用offset,两字节比较用short,四字节比较用long
用户希望的值,若datea-type为串比较,则可以是任何字符串,可以包括UNIX转义序列. 若为字节比较则必须是一个数字
若测试成功,file会打印的值
使用sed将所有空白行删掉
#!/bin/sed -f /^[ ]*$/d
使用sed的G命令可以实现功能. sed的G命令附加了一个换行符和sed所保留空格的内容.
增加一行空白间距的方法为
exec /bin/sed G $@
同理,增加2行空白间距的方法为
exec /bin/sed 'G;G' $@
可以通过临时设置环境变量TZ的值,然后执行date的方式,来获得其他地区的时间. 例如
(TZ=Japanf9;date) # 获取日本现在的时刻
export后的shell变量就是环境变量. subshell会从shell中继承所有的环境变量,但不会继承shell变量
执行cd foo时,shell会先尝试进入当前目录的foo目录下,若失败,则会遍历CDPATH中的各目录,并一一尝试进入其中的foo目录下
CDPATH=:~ # 注意最开始的:,它是一个空记录项,表示当前目录,若没有这个当前目录的记录,则无论是sh还是ksh都无法cd到当前目录的子目录中!!bash不存在这个问题 cd ~/bin cd bin # 若不存在~/bin/bin目录,则进入~/bin目录下
启动vi或ex编辑器时,会自动执行保存在~/.exrc内的初始化命令.
初始化命令可以是set,ab和map. 注释由双引号"开头.
由于该文件实际上是进入vi前由ex读取的,因此exrc中的命令不应该有前置的冒号
除了.exrc文件外,还可以在其他文件中保持设置的选项,并在vi中用:so命令来读取.
因此:e#的意思是切换到另一个替换文件,功能等同于C-^
:w %.bak的意思是
:.,600w newfile 把当前行到第600行的内容写入newfile中
:.,600w >>newfile 可以把当前行到600行的内容添加到newfile中,而不覆盖原newfile的内容
象/Los Alamos/;/treasure/表示找到出现在Los Alamos后的treasure处,即使这两个短语可能不在同一行.
类似于/Los Alamos然后再/treasure. 不同的是,它可以使用n命令来重复搜索
可以通过设置tags的属性来设置多个tags文件.
:ab 缩写 全称
还可以用:unab 缩写来取消缩写词定义.
:ab 则会列出当前已定义的缩写词
需要特别说明的是: ab定义的缩写词,对ex模式也生效,事实上,对ex模式下的命令,用缩写词比用键映射更好.
:set directory=/some/place/new
使用map智能在命令模式下定义宏.
使用map!的作用类似map,但是map!在文本输入模式下起作用,它的功能类似ab
vi虽然不支持使用q来定义宏,但是支持用@来执行宏.
在.profile中放入下面一句:
TERM=`qterm`;export TERM
set -xv
通过输入stty erase {控制字符} 可以将{控制字符}设定为删除键.
stty让用户用两个字符的组合char来代表一个控制键. 其中^就是键^本身,而{char}是任意的单个字符. 可能需要在{char}前放入一个,以防止shell将其解释为一个通配符
例如
stty erase ^h stty erase ^\?
stty可以改变的功能包括:
用stty -a会显示用户当前所有终端的设置. werase和rprnt字符有些UNIX版本未实现.
可以通过搜索/etc/termcap文件内容或者通过列出在/usr/lib/terminfo目录结构中的文件名来寻找终端名,以方便地设置TERM
split -N bigfile # 每N行分割一个文件,分割产生的文件以xaa,xab这样命名 split -N bigfile bigfile.split. # 每N行分割一个文件,分割产生的文件以bigfile.split.aa,bigfile.split.ab这样命名
split_line=$1 file=$2 total_line=$(wc -l $file |cut -d " " -f1) prefix=$file.split. i=1 begin_line=1 while [ $begin_line -le $total_line ] do end_line=$(echo "$begin_line+$split_line" |bc) sed "$begin_line,$end_line!d" $file >$prefix$i i=$(echo "$i+1" |bc) begin_line=$(echo "$end_line+1"|bc) done
split -b N bigfile # 以N个字节来分割 split -b N bigfile prefix. # 以N个字节来分割,且分割的文件前缀为prefix.
split_byte=$1 file=$2 total_byte=$(wc -c <$file) prefix=$file.split. i=1 begin_byte=1 while [ $begin_byte -le $total_byte ] do dd of=$prefix$i bs=$split_byte count=1 2>/dev/null i=$(echo "$i+1" |bc) begin_byte=$(echo "$begin_byte+$split_byte" |bc) done <$file
若希望并排粘贴N个文件的内容,则可以使用paste命令
paste <(ls) <(ls -r) # my-byte-split.sh my-line-split.sh # my-line-split.sh my-byte-split.sh
合并的数据流默认情况下使用TAB分割,但是可以用-d选项来指定分隔符。
join会在文件中搜索某些列,找到相互匹配的行之后,它会在该列的位置上把两列文本粘帖在一起
默认join会以第一列的内容进行匹配,也可以使用-1 FIELD和-2 FIELD来指定file1和file2的FIELD列
需要注意的是:
uniq file1 file2
的意思是用file1的唯一行代替file2的内容
``` sh sort +2 -3 +0 -2 phonelist # 先根据第2列的值排序,再根据第0列和第1列的值进行排序 ```
``` sh sort +2 -3 +0 -2 +3n phonelist # 先根据第2列的值排序,再根据第0列和第1列的值进行排序,最后根据第三列进行数字排序 ```
{TAB}12 345 678中参与第0列排序的是{TAB}12而不是12
#! /bin/sh awk 'BEGIN { FS=RS } {print length,$0}' $* | sort +0n -1 | # 根据数字大小进行排序 sed 's/^[0-9][0-9]*//' # 删除数字大小
case i in ?) # 匹配只有1个字符的字符串 ;; ?*) # 匹配有一个或多个字符的字符串 ;; [yY]|[yY][eE][sS]) # 匹配y,Y或者YES,Yes,YeS等 ;; /*/*[0-9]) # 匹配以/开始并且至少再包含一个/的一数字结尾的文件路径名,例如/xxx/yyy/somedir/file2 ;; 'what now?') # 匹配模式what now?。引号告诉shell按字面意思解释 ;; "$msgs") # 匹配$msgs变量的内容。双引号允许shell替换变量的值 ;; *) # 匹配所有的值,起默认值的作用
trap "command1;command2…" sign1 sign2…
捕获到sign1,sign2…等信号后,执行command1;command2
使用set 新参数1 新参数2…能够初始化脚本的参数。
#set_test.sh echo before set : $@ set 1 2 echo after set : $@ # set_test.sh 3 4 # before set : 3 4 # after set : 1 2
但要注意的是,若新参数以-开头的,则shell会把它看出是自己的选项。
jot 要产生多少个参数 [起始参数值 结束参数值]
exec command会执行comand来代替当前shell,它常常用于shell脚本的最后一个命令.
但exec也可以用来重定向当前shell脚本的IO,例如
exec < formfile
上面命令使得当前shell中所有命令的标准输入来自于文件formfile
:操作符会计算它的参数值,并返回0退出状态,它可以用来
#!的原理实际是将脚本名作为参数拼接到#!后面的程序后面来运行该脚本的. 例如
#! /bin/bash #假设该脚本名称为test.sh commands...
则在直接执行该脚本时,内核实际上执行的是
/bin/bash test.sh
这也是为什么用awk作为#!行的命令解释程序时,需要加-f的原因,因为-f表示用从文件中读取脚本.
#! /usr/bin/awk -f {print $2}
因此使用#!/bin/cp可以制作自复制脚本. 将它放到名为zap的文件中,运行zap zup,则会有一份zup的自拷贝
另外,需要注意,内核不会去搜索PATH路径,因此#!中的解释程序必须使用绝对路径.
使用trap : sign1 sign2…
会忽略信号,向子进程传递信号
使用stty -echo就能关闭回显,这样用户的输入就不会显示在屏幕上了
echo "enter the password" stty -echo read pwd stty echo
sh<file若file中有无法进行read操作
掩码只会在文件存在时起作用.如果文件尚不存在,掩码就不会应用于它. 基于该特性,可以创建一个锁文件
name = $(basename $0) LOCKFILE=/tmp.lock.$name until (umask 222;echo $$ >$LOCKFILE) 2>/dev/null # 若已 存在锁文件,则该操作失败,否则成功 do sleep 5 done rm -f $LOCKFILE
事实上,可以通过如下命令来创建模式为000的文件
(umask 666;echo hi >afile)
The text was updated successfully, but these errors were encountered:
你为何如此优秀?
Sorry, something went wrong.
No branches or pull requests
shell
shell分类
loginshell=yes
,然后就可以通过if [ -n "$loginshell" ]
来判断shell的类型如何判断用户从不同终端登录
如何在sh退出时自动执行命令
在C shell中有一个名为.logout的设置文件. 当用户退出时.logout中的命令被执行. 但是Bourne 和Korn shell中都没有退出文件. 可以使用一下方式模拟
如何防止shell意外退出
可以通过设置ignoreeof这个shell变量来解决问题:
对于C shell执行
set ignoreeof
对于bash或ksh使用
set -o ignoreeof
shell解释命令行的步骤是怎样的
如何使用echo信息到标准错误中
如何强制bash执行外置/内置命令?
在命令前输入command即可以禁止shell函数查找
在命令前输入builtin
只需要给出外部命令的全路径即可.
/bin/echo hi # 明确指明使用哪个外部命令
或者也可以使用enable -n将某个/某几个内置bash命令无效化. enable的影响将一直持续到用户退出shell为止.
如何禁止here Document中的变量替换和命令替换呢?
可以在EOF标识前放一个反斜杠
shell中通配符与{}模式的区别
通配符匹配只对已经存在的文件名作扩展.
而{}模式,则可以对任意文本进行扩展,{}的用法为{扩展1,扩展2,扩展3…}. 例如
ksh和bash中的变量编辑
Table 1: ksh和bash中的变量编辑操作符其中pattern采取的是通配符模式,而不是正则表达式. 例如
bash中的进程替换
bash中的<(process)被用来执行process并将输出送到一个命令的命名管道中.
可以把它想象成一个文件名参数,文件的内容就是process执行的结果.
若使用的shell没有这个功能,可以用一个shell脚本来代替,该脚本执行一个命令,并将其输出保持到一个临时文件中,然后将临时文件名放到它的标准输出中.
shell中的历史替换机制
ksh和bash中,设置变量HISTSIZE的值即可
使用history [N]列出所有/后N个命令
!N
来执行编号为N的命令比较文件差异
输出的结果为如何将file1变成file2的过程,描述使用了ed的命令说明(c为修改行,d为删除行,a为添加行)
可以使用-e选项来输出供ex/ed使用的脚本
输出的结果为如何将file2和file3变成file1的过程,描述使用了ed的命令说明(c为修改行,d为删除行,a为添加行)
可以使用-e选项来输出供ex/ed使用的脚本
diff的输出大量使用了ed的命令来说明,难以理解,可以使用ediff,它会将说明翻译为英文
file1和file2必须是已经排过序的
comm命令显示三列信息
要想不显示那一列的信息,使用-N选项即刻.
shell的作业控制
正常情况下,后台运行的作业也会把输出输出到用户的屏幕上,这样容易搞乱屏幕. 可以使用stty tostop命令来让试图对终端写入的后台作业停止运行.
若后台作业因为输出到终端而停止,则shell会打印出一条信息:
\+ stopped (tty output) somejob
shell的IO重定向
默认情况下,只有命令的表示输出才回发送到管道中,若要仅将标准错误发送給管道可以使用subshell. 如下所示
或者使用如下方式交换stderr和stdout
在bash/ksh中设置
set -o noclobber
后,则shell将不允许IO重定向破坏一个已经存在的文件. 除非在重定向的符号之后添加一个!来显式的通知他.{ date who ls } > log
使用{}列表与sushell的不同在与,{}的所有操作都是基于当前shell来操作的.
若希望一个程序的输出重定向到一个文件的同时也在屏幕上输出,则可以使用tee命令.
tee命令会将它的标准输入写入到一个文件中,并将相同的文本写入到他的标准输出中.它的格式为:tee [-a] file
ksh的文件通配符说明
匹配0个或1个abc
匹配0个或多个abc
匹配1个或多个abc
匹配不包含abc的任何字符串
tar命令
使用tar打包目录到标准输出|从标准输出tar解包
tar的X标志后接一个文件,文件的内容就是排除打包的文件路径列表
使用-C标识,可以指定tar在打包前先进入指定目录,然后就可以指定相对路径打包了
这是因为,tar实际上是为磁带归档所设计的. 它会在每个文件的末尾加上垃圾空字符以沾满一个块的空间,因此实际上一个大的tar文件和里面单独小文件所占用的磁盘块差不多.
但是可以通过对tar包进行压缩的方式来解决这个问题,因为大量的空字符实际上非常适用于压缩算法.
find命令
提高find的性能
创建find数据库
创建cron定时运行该脚本.
创建一个shell脚本来使用这个数据库
ln命令
ln f1 f2 f3 /tmp # 在/tmp下创建名为f1 f2 f3的链接
cat命令
tail命令
su命令
expr命令
语法
expr arg1 operator arg2 [operator arg3…]
返回值
如果表达式的值非0并且非空,那么expr的退出状态值为0;如果表达式的值为0或者空,则退出状态值为1;如果表达式无效,则退出状态值为2
operator操作符
若arg2模式被放入(和)中,则输出为与之相匹配的arg1的一部分.
否则仅仅输出匹配字符的数目. 模式匹配时从arg1的起始位置开始
bc命令进行数学运算
需要注意的是,若先设置ibase=N,再设置obase=M时,M已经是以N进制来计算了,例如
之所以结果为11是因为obase的16使用的是8进制,它的值其实是14
yes命令生成任意大小的文件
yes会不断重复地输出它的参数(默认为y),使用它和head命令一起可以生成任意长度大小的文件. 例如
要生成每行8个字符(7个数字和一个换行符),共12800行的文件,则输入
其他
change time是对文件的inode进行修改,比如文件名,权限等
modification time是对文件的内容进行修改
但若是跨文件系统移动文件,那么被移动的文件的所有者将改为你.
这时因为,在跨文件系统移动时,mv实际上必须拷贝该文件,并删除原文件
一般情况下,若一个用户又对某目录的写权限,则它可以对该目录中的文件进行重命名或者删除操作–即使文件并不属于该用户.
通过设置目录的sticky位(1000)可以使得只有文件的所有者,目录的所有者和超级用户才能对文件进行重命名或删除.
终端的标准输出被映射成了/dev/中的tty文件了,而clear清除屏幕的方法是通过TERMINFO查询终端的清除键序列,然后输出该键序列到标准输出中.
因此,若终端类型一致,且用户具有对/dev/tty文件的写权限的化,可以通过clear>/dev/tty来实现清空其他终端上内容
假设某个进程会不断的写日志到~/logfile中,而该日志并无用处,则可以
ln /dev/null ~/logfile
通过修改/etc/magic能够增加可识别的文件类型
/etc/magic有四个字段:
offset data-type value file-type
使用sed将所有空白行删掉
使用sed的G命令可以实现功能. sed的G命令附加了一个换行符和sed所保留空格的内容.
增加一行空白间距的方法为
同理,增加2行空白间距的方法为
环境变量
常用的环境变量
如何显示其他地区现在的时间?
可以通过临时设置环境变量TZ的值,然后执行date的方式,来获得其他地区的时间. 例如
环境变量和shell变量的区别
export后的shell变量就是环境变量. subshell会从shell中继承所有的环境变量,但不会继承shell变量
使用CDPATH变量为用户改变目录节省时间
执行cd foo时,shell会先尝试进入当前目录的foo目录下,若失败,则会遍历CDPATH中的各目录,并一一尝试进入其中的foo目录下
获取路径中目录信息的几种方法
组织$HOME目录
- ~/private存放私人文件,将权限设为700
vi
启动vi或ex编辑器时,会自动执行保存在~/.exrc内的初始化命令.
初始化命令可以是set,ab和map. 注释由双引号"开头.
由于该文件实际上是进入vi前由ex读取的,因此exrc中的命令不应该有前置的冒号
除了.exrc文件外,还可以在其他文件中保持设置的选项,并在vi中用:so命令来读取.
因此:e#的意思是切换到另一个替换文件,功能等同于C-^
:w %.bak的意思是
:.,600w newfile 把当前行到第600行的内容写入newfile中
:.,600w >>newfile 可以把当前行到600行的内容添加到newfile中,而不覆盖原newfile的内容
象/Los Alamos/;/treasure/表示找到出现在Los Alamos后的treasure处,即使这两个短语可能不在同一行.
类似于/Los Alamos然后再/treasure. 不同的是,它可以使用n命令来重复搜索
可以通过设置tags的属性来设置多个tags文件.
:ab 缩写 全称
还可以用:unab 缩写来取消缩写词定义.
:ab 则会列出当前已定义的缩写词
需要特别说明的是: ab定义的缩写词,对ex模式也生效,事实上,对ex模式下的命令,用缩写词比用键映射更好.
:set directory=/some/place/new
vi的命令模式映射:
使用map智能在命令模式下定义宏.
使用map!的作用类似map,但是map!在文本输入模式下起作用,它的功能类似ab
vi的宏定义
vi虽然不支持使用q来定义宏,但是支持用@来执行宏.
设置终端
登录时设置终端类型
在.profile中放入下面一句:
登录时,若挂起怎么办?
set -xv
,让shell进入调试模式使用stty设置删除,终止和终端字符
通过输入stty erase {控制字符} 可以将{控制字符}设定为删除键.
stty让用户用两个字符的组合char来代表一个控制键. 其中^就是键^本身,而{char}是任意的单个字符. 可能需要在{char}前放入一个,以防止shell将其解释为一个通配符
例如
stty erase ^h stty erase ^\?
stty可以改变的功能包括:
Table 2: 用stty设置的键用stty -a会显示用户当前所有终端的设置. werase和rprnt字符有些UNIX版本未实现.
从哪里寻找可能可以使用的终端类型
可以通过搜索/etc/termcap文件内容或者通过列出在/usr/lib/terminfo目录结构中的文件名来寻找终端名,以方便地设置TERM
文本处理
分割文本
按行数分割
按字节数分割
按列粘贴文本
若希望并排粘贴N个文件的内容,则可以使用paste命令
合并的数据流默认情况下使用TAB分割,但是可以用-d选项来指定分隔符。
匹配连接两个文本的内容
join会在文件中搜索某些列,找到相互匹配的行之后,它会在该列的位置上把两列文本粘帖在一起
默认join会以第一列的内容进行匹配,也可以使用-1 FIELD和-2 FIELD来指定file1和file2的FIELD列
uniq用来删除以排序的文件中相邻文本行的重复内容
需要注意的是:
uniq file1 file2
的意思是用file1的唯一行代替file2的内容
使用sort对文本进行排序
shell编程
case语句中的模式匹配
trap捕获信号量
trap "command1;command2…" sign1 sign2…
捕获到sign1,sign2…等信号后,执行command1;command2
Table 3: 一些用于trap命令的UNIX信号编号使用getopt/getopts处理脚本的参数解析
使用set命令重新初始化脚本的参数
使用set 新参数1 新参数2…能够初始化脚本的参数。
但要注意的是,若新参数以-开头的,则shell会把它看出是自己的选项。
使用jot命令产生数组
jot 要产生多少个参数 [起始参数值 结束参数值]
使用exec可以重定向shell脚本的IO
exec command会执行comand来代替当前shell,它常常用于shell脚本的最后一个命令.
但exec也可以用来重定向当前shell脚本的IO,例如
上面命令使得当前shell中所有命令的标准输入来自于文件formfile
:操作符
:操作符会计算它的参数值,并返回0退出状态,它可以用来
#!的原理
#!的原理实际是将脚本名作为参数拼接到#!后面的程序后面来运行该脚本的. 例如
则在直接执行该脚本时,内核实际上执行的是
这也是为什么用awk作为#!行的命令解释程序时,需要加-f的原因,因为-f表示用从文件中读取脚本.
因此使用#!/bin/cp可以制作自复制脚本. 将它放到名为zap的文件中,运行zap zup,则会有一份zup的自拷贝
另外,需要注意,内核不会去搜索PATH路径,因此#!中的解释程序必须使用绝对路径.
如何将捕获到的信号传递给子进程?
使用trap : sign1 sign2…
会忽略信号,向子进程传递信号
参数替换操作符
为了保护密码而关闭回显
使用stty -echo就能关闭回显,这样用户的输入就不会显示在屏幕上了
sh<file与sh file有时候那么区别?
sh<file若file中有无法进行read操作
创建锁文件,防止多个进程同时操作
掩码只会在文件存在时起作用.如果文件尚不存在,掩码就不会应用于它. 基于该特性,可以创建一个锁文件
事实上,可以通过如下命令来创建模式为000的文件
The text was updated successfully, but these errors were encountered: