Blog

renice命令

Content #

renice可以修改系统中已运行命令的优先级。它通过指定运行进程的PID来改变其优先级: $ ./jobcontrol.sh > jobcontrol.out & [2] 16642 $ $ ps -p 16642 -o pid,ppid,ni,cmd PID PPID NI CMD 16642 1630 0 /bin/bash ./jobcontrol.sh $ $ renice -n 10 -p 16642 16642 (process ID) old priority 0, new priority 10 $ $ ps -p 16642 -o pid,ppid,ni,cmd PID PPID NI CMD 16642 1630 10 /bin/bash ./jobcontrol.sh $ renice命令会自动更新运行进程的调度优先级。和nice命令一样,renice命令对于非特权用户也有一些限制:只能对属主为自己的进程使用renice且只能降低调度优先级。但是,root用户和特权用户可以使用renice命令对任意进程的优先级做任意调整。

From #

Linux命令行与shell脚本编程大全

nice命令

Content #

nice命令允许在启动命令时设置其调度优先级。要想让命令以更低的优先级运行,只需用nice命令的-n选项指定新的优先级即可: $ nice -n 10 ./jobcontrol.sh > jobcontrol.out & [2] 16462 $ $ ps -p 16462 -o pid,ppid,ni,cmd PID PPID NI CMD 16462 1630 10 /bin/bash ./jobcontrol.sh $ 注意,nice命令和要启动的命令必须出现在同一行中。ps命令的输出证实,谦让度(NI列)已经调整到了10。

nice命令使得脚本以更低的优先级运行。但如果想提高某个命令的优先级,那么结果可能会让你大吃一惊: $ nice -n -5 ./jobcontrol.sh > jobcontrol.out & [2] 16473 $ nice: cannot set niceness: Permission denied

$ ps -p 16473 -o pid,ppid,ni,cmd PID PPID NI CMD 16473 1630 0 /bin/bash ./jobcontrol.sh $ nice命令会阻止普通用户提高命令的优先级。注意,即便提高其优先级的操作没有成功,指定的命令依然可以运行。只有root 用户或者特权用户才能提高作业的优先级。 nice命令的-n选项并不是必需的,直接在连字符后面跟上优先级也可以: $ nice -10 ./jobcontrol.sh > jobcontrol.out & [2] 16520 $ $ ps -p 16520 -o pid,ppid,ni,cmd PID PPID NI CMD 16520 1630 10 /bin/bash ./jobcontrol.sh $ 然而,当要设置的优先级是负数时,这种写法则很容易造成混淆,因为出现了双连字符。在这种情况下,最好还是使用-n选项。

...

sub:谦让度(nice value)

Content #

在多任务操作系统(比如Linux)中,内核负责为每个运行的进程分配CPU时间。调度优先级[也称为谦让度(nice value)]是指内核为进程分配的CPU时间(相对于其他进程)。在Linux系统中,由shell启动的所有进程的调度优先级默认都是相同的。

调度优先级是一个整数值,取值范围从-20(最高优先级)到+19(最低优先级)。在默认情况下,bash shell以优先级0来启动所有进程。

提示: -20(最低值)代表最高优先级,+19(最高值)代表最低优先级,这很容易记混。只要记住那句俗话“好人难做。”(Nice guys finish last.)即可。越是“谦让”(nice)或是值越大,获得CPU的机会就越低。

nice命令 renice命令

From #

Linux命令行与shell脚本编程大全

nohup命令

Content #

有时候,即便退出了终端会话,你也想在终端会话中启动shell脚本,让脚本一直以后台模式运行到结束。这可以用nohup命令来实现。 nohup命令能阻断发给特定进程的SIGHUP信号。当退出终端会话时,这可以避免进程退出。 nohup命令的格式如下:

nohup command

下面的例子使用一个后台脚本作为command: $ nohup ./testAscript.sh & [1] 1828 $ nohup: ignoring input and appending output to ’nohup.out' $ 和普通后台进程一样,shell会给command分配一个作业号,Linux系统会为其分配一个PID号。区别在于,当使用nohup命令时,如果关闭终端会话,则脚本会忽略其发送的SIGHUP信号。

由于nohup命令会解除终端与进程之间的关联,因此进程不再同STDOUT和STDERR 绑定在一起。为了保存该命令产生的输出,nohup命令会自动将STDOUT和STDERR 产生的消息重定向到一个名为nohup.out的文件中。

注意:nohup.out文件一般在当前工作目录中创建,否则会在$HOME目录中创建。

nohup.out文件包含了原本要发送到终端显示器上的所有输出。进程结束之后,可以查看nohup.out文件中的输出结果: $ cat nohup.out This is Test Script #1. $ nohup.out文件中的输出结果和脚本在命令行中运行时产生的一样。注意:如果使用nohop运行了另一个命令,那么该命令的输出会被追加到已有的 nohup.out文件中。当运行位于同一目录中的多个命令时,一定要当心,因为所有的命令输出都会发送到同一个nohup.out文件中,结果会让人摸不着头脑。

From #

Linux命令行与shell脚本编程大全

修改或移除信号捕获

Content #

要想在脚本中的不同位置进行不同的信号捕获处理,只需重新使用带有新选项的 trap命令即可:

$ cat trapmod.sh
#!/bin/bash
#Modifying a set trap
#
trap "echo ' Sorry...Ctrl-C is trapped.'" SIGINT
#
count=1
while [ $count -le 3 ]
do
     echo "Loop #$count"
     sleep 1
     count=$[ $count + 1 ]
done
#
trap "echo ' I have modified the trap!'" SIGINT
#
count=1
while [ $count -le 3 ]
do
     echo "Second Loop #$count"
     sleep 1
     count=$[ $count + 1 ]
done
#
exit
$

修改了信号捕获之后,脚本处理信号的方式就会发生变化。但如果信号是在捕获被修改前接收到的,则脚本仍然会根据原先的trap命令处理该信号。 $ ./trapmod.sh Loop #1 ^C Sorry…Ctrl-C is trapped. Loop #2 Loop #3 Second Loop #1 Second Loop #2 ^C I have modified the trap! Second Loop #3 $ 如果在交互式shell会话中使用trap命令,可以使用trap -p查看被捕获的信号。如果什么都没有显示,则说明shell会话按照默认方式处理信号。

...

脚本退出时捕获EXIT信号

Content #

要捕获shell脚本的退出,只需在trap命令后加上EXIT信号即可:

$ cat trapexit.sh
#!/bin/bash
#Testing exit trapping
#
trap "echo Goodbye..." EXIT
#
count=1
while [ $count -le 5 ]
do
     echo "Loop #$count"
     sleep 1
     count=$[ $count + 1 ]
done
#
exit
$
$ ./trapexit.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
Goodbye...
$

当脚本运行到正常的退出位置时,触发了EXIT,shell执行了在trap中指定的命令。如果提前退出脚本,则依然能捕获到EXIT: $ ./trapexit.sh Loop #1 Loop #2 Loop #3 ^CGoodbye… $ 因为SIGINT信号并未在trap命令的信号列表中,所以当按下Ctrl+C组合键发送 SIGINT信号时,脚本就退出了。但在退出之前已经触发了EXIT,于是shell会执行trap命令。

From #

Linux命令行与shell脚本编程大全

捕获信号(Bash)

Content #

trap命令可以指定shell脚本需要侦测并拦截的Linux信号。如果脚本收到了trap 命令中列出的信号,则该信号不再由shell处理,而是由本地处理。

trap命令的格式如下:

trap commands signals

在trap命令中,需要在commands部分列出想要shell执行的命令,在signals部分列出想要捕获的信号(多个信号之间以空格分隔)。指定信号的时候,可以使用信号的值或信号名。

下面这个简单的例子展示了如何使用trap命令捕获SIGINT信号并控制脚本的行为:

$ cat trapsignal.sh
#!/bin/bash
#Testing signal trapping
#
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
#
echo This is a test script.
#
count=1
while [ $count -le 5 ]
do
     echo "Loop #$count"
     sleep 1
     count=$[ $count + 1 ]
done
#
echo "This is the end of test script."
exit
$

每次侦测到SIGINT信号时,本例中的trap命令都会显示一行简单的文本消息。捕获这些信号可以阻止用户通过组合键Ctrl+C停止脚本: $ ./trapsignal.sh This is a test script. Loop #1 Loop #2 ^C Sorry! I have trapped Ctrl-C Loop #3 ^C Sorry! I have trapped Ctrl-C Loop #4 Loop #5 This is the end of test script. $ 每次使用Ctrl+C组合键,脚本都会执行trap命令中指定的echo语句,而不是忽略信号并让shell停止该脚本。

...

诗人的形象就像是神箭手菲罗克忒忒斯

Content #

诗人的确是异类。英国的一位文学教授是这么说的:《伊利亚特》中有一个神箭手菲罗克忒忒斯,功夫了得,但身上有一个伤口,伤口总散发恶臭,希腊人就让他单独住在一个小岛上。特洛伊久攻不下,希腊人想起来,我们还有一个神箭手呢,派人去请他。诗人的形象就像是神箭手菲罗克忒忒斯,有很厉害的本事,但普通人没法忍受跟他生活在一起。诗人总让人觉得,他就是个外人。

From #

文学体验三十讲

小说的智慧则是顾左右而言他

Content #

昆德拉最出名的小说是《生命中不能承受之轻》。开头第一部第一节是哲学思考,讲永世轮回的问题,第二节还是思考,讲轻和重,第三节讲人物了,“多年来,我一直想着托马斯”。好像有了第一人称的叙述者,但后面你发现这个“我”只是一个思考者,托马斯的故事在进行,思考者也在思考。昆德拉把哲学随笔和小说故事糅合在一起,每个章节都不是很长,读起来很顺。他说在写《生命中不能承受之轻》的时候,他意识到人物编码是一些不同的关键词,特丽莎是肉体、灵魂、眩晕、软弱、田园诗等,托马斯的关键词就是轻和重。昆德拉用小说进行思考。他塑造人物,会用几个关键词来编码,然后又在小说中讨论这些词。小说第三部就叫“未解之词”,讨论什么叫忠诚与背叛。最后一部,一边讲故事,一边在讲到底什么叫田园牧歌似的生活。他不是像哲学家那样从观念出发进行思考,他是从人的境遇开始思考:一个人遭遇什么样的故事,他处在什么样的情景之中。我们都说生活的负担太沉重了,那什么是生命中不能承受之轻?生命只有一次,没有彩排,那我们怎么进行选择呢?为什么生活在别处?为什么生活不能在此处进行?为什么人与强权的斗争,就是与遗忘的斗争呢?昆德拉提出这些问题,并不是他能给出答案,他只是提出问题,告诉我们生活需要审视,告诉我们生活的复杂性之所在。有时,我们感到生活困难重重,从生存的本质上却提不出什么独特的问题。钱太少了,不够花的,怎么办?这是个长期有效的问题,巴尔扎克处理过这个问题,陀思妥耶夫斯基处理过这个问题。有答案吗?没有。一个异乡人,来到一个自成一体的地方,却无法融入其中,他似乎永远被关在门外,他该怎么办?卡夫卡处理过这个问题。有答案吗?没有。我们年纪渐长,就会知道,哟,世上有那么多问题是无解的。小说家讨厌的地方在于,他告诉你,还有很多新的无解的问题。昆德拉在一篇访谈里说,小说家的工作就是编一些故事,询问世界。人类的愚蠢就在于有问必答,小说的智慧则在于对一切提出问题。

科学问题可能是有问必答的,哲学问题很可能是所答非所问的,小说的智慧则是顾左右而言他。

From #

文学体验三十讲

哈代与纳博科夫

Content #

好多年之后,我读一本文学理论书《由书而梦》,这本书讲的就是文字如何指引你在头脑中进行想象。里面提到哈代的景物描写,是写苔丝步行去奶牛场,路上有绿色青苔,幽静山林。她看到奶牛:“此时,落到草棚后面的夕阳把这群耐性很好的牛群的影子,准确无误地映射到草棚的墙上。每天傍晚,这些模糊的、简单身形的影子都会被夕阳投射出去,认真勾勒好每一个轮廓,如同宫廷墙壁上那些宫廷美人的侧影,如同许久前天神在大理石壁上描绘奥林匹斯,或是把恺撒和埃及法老的轮廓描画出来那样,用心描绘它们。”

这一段写的是什么呢?就是傍晚,光线最柔和的时候,夕阳把奶牛的影子给投射到草棚的墙上。那为啥还要说到宫廷美人、奥林匹斯天神、恺撒和埃及法老呢?作家想让你在这里停留一下,去凝视那些光影,想得更多一点儿。你得注意,这是一百三十年前的小说,那时候人们还不知道什么叫电影,也没多少人用过照相机,人们读小说,读作家描写景色、描写环境,读里面的人物一步步是怎么行动的,就是在脑子里过一遍电影。我读完这本理论书,特意把《苔丝》的原著小说拿出来读一遍,又把电影找出来看一遍,我觉得两者大体都是吻合的,电影激发的想象比文字还要更美一些,几乎每个镜头都像画一样,讲究构图。人在想象的时候,很容易想到一个物品、一个环境,但如果没经过美术训练,很难有构图的意识。不过,现在的人都有照相机,看到美丽的东西,都会凝视,可能还会拍摄,在拍照的时候,就会考虑光线、光影的明暗、构图,哈代写奶牛场的环境,写夕阳和影子,拍照的人很容易就能获得审美体验。我们拿手机随便拍个什么东西,都会想一下怎么拍更美,这说明我们的审美体验不是只靠文字获得的。我们有手机,手机能拍照片,能拍视频,所以我们也就对照片、对影视作品有天然的亲近感。我们有手机就知道推拉摇移,就知道构图和景深,我们写文章才知道所谓起承转合。所以,我们现在再读哈代那样的作品,会觉得,哦,太古典了吧。

一百多年过去,图像已经有了翻天覆地的变化,文字,作为一种表达工具,还跟原来差不多。这个话题太复杂,我来介绍一篇文章,我们来体会一下文字的力量、文字和影像的关系,还有文字在头脑中会激发什么样的画面。这篇文章就是纳博科夫《说吧,记忆》中的第一章,最早是一九五〇年四月发表在《纽约客》杂志上的。我第一次读这篇文章的时候都不敢读完,就像你听一个人唱歌,起的调门儿太高了,你害怕他唱不上去。我读的时候,就感觉纳博科夫的句子太讲究了,每一个句子都太美、太繁复了,用这么美的句子写一篇文章写一本书,能不能自始至终都在这个调门儿上啊?我们来看看他的第一段——

我认识一个年轻的时间恐惧者,当他第一次看着他出生前几个星期家里拍摄的电影时,他体验到一种类似惊恐的感情。他看见了一个几乎没有任何变化的世界——同样的人,同样的房子——然后意识到在那里他根本就不存在,而且没有人为缺少他而难过。他瞥见他的母亲在楼上的一扇窗口挥手,那个不熟悉的手势使他心神不安,仿佛那是种神秘的告别。但是特别使他害怕的是看到一辆放在门廊里的崭新的婴儿车,带着棺材所具有的自鸣得意、侵蚀一切的神气,就连那儿也是空的,仿佛,在事物的进程反向发展的过程中,他自己的身体已经分崩离析。

我试着来解释一下这一段。我们每个人都会看到自己小时候的照片,可能是刚满月的时候拍的,可能是一百天的时候拍的,但纳博科夫看到了什么呢?似乎是一段他出生前几个星期的家庭影片,家里的样子很熟悉,只是他还没出生,婴儿车已经买回来了,妈妈在挥手,像是在跟什么东西告别。为什么说到婴儿车,说它的气息跟棺材似的呢?因为在他出生之前,一切都在虚无中,在他死了并躺在棺材里之后,万物也在虚无中。出生之前,死了之后,是两个永恒的黑暗。所以,纳博科夫这一段开头有一句话:“我们的生存只不过是两个永恒的黑暗之间瞬息即逝的一线光明。”文字能让你看到比较容易想到的东西:母亲挥手的姿态,婴儿车。但文字也激发你去想象你看不到的东西:婴儿车和棺材之间的联系,生命的尽头是躺在棺材里,生命的起点是一辆婴儿车,只是往前追溯的时候,你的身体可能也消失了,之前是你还未存在的时光。文字让你去看根本不可能看到的东西。纳博科夫提醒你,别只看你衰老之后要前往的那个深渊,也去看看你出生前的那个深渊,这两样东西我们哪里看得见?照相机也拍摄不出来。但是你能感受到某种气氛:一辆婴儿车静静等着你出生,让你感受到一种时间的恐惧,那是你还没开始的时间,时间并不因你而存在,也不会因你的消亡而停止。这开头第一段太需要读者的想象力,所以作者在第二段说:“想象,是不朽和不成熟的人的极顶快乐,应该受到限制,为了能够享受生活,我们不应过多地享受想象的快乐。”这句话真是充满了写作者的优越感。

纳博科夫,俄国作家,俄国革命之后在欧洲流亡,然后去了美国,在大学里教授俄国文学,五十六岁时出版了《洛丽塔》,一下成为畅销书作家,而后到瑞士生活,在蒙特勒去世。他年幼时家里有五十个用人,有法语家庭教师,有英语家庭教师,他说他度过了最美好的童年。他爸爸是财主,一家人去家里的农庄度假,在大宅子里吃饭,乡下人就来求见老爷,要点儿钱,要砍掉地主家的几棵树,要收割地主家的一点儿庄稼,他爸爸都会同意,乡下人就会把老爷举起来,扔到空中,表示感谢。纳博科夫和弟弟、妈妈在屋里接着吃饭,透过窗户,能看见爸爸被扔起来。这是《说吧,记忆》第一章的结尾处,他是这么写的——

从我坐的地方,我会突然透过西面的一扇窗子,看见升空的壮观实例。在那儿,有一小会儿,父亲身穿被风吹得飘起的白色夏季西装的身影会出现,在半空中壮观地伸展着身体,四肢呈奇怪的随意姿态,沉着英俊的面孔向着天空,随着看不见的人将他有力地向上抛,他会像这个样子三次飞向空中,第二次会比第一次飞得高,在最后最高的那次飞行中,他仿佛是永远斜倚着,背衬夏季正午的蓝色苍穹,就像那些自在地高飞在教堂穹形天花板上的、衣服上有那么多褶子的天堂中的角色,而在他们下面,凡人手中的蜡烛一根根点燃,在烟雾蒙蒙中微小的火焰密集成一片,神父吟诵着永恒的安息,葬礼用的百合花在游弋的烛光下遮挡住躺在打开的灵柩中的不论什么人的脸。(王家湘译)

父亲被扔在空中,飞得很高,就像是斜躺在蓝色的天空中,就像是飘在教堂穹顶上的人物一样,就像是飘在天堂上,下面有烛光,有牧师在祷告,有一具棺材,有一个面目不清的人,有百合花,显然是一场葬礼。纳博科夫把他爸爸给写死了,刚才还好好的一个乐善好施的财主,怎么一两句话之间就死了,就变成天堂中的角色了呢?电影中这种跨越时空的转换很常见,你看《阳光灿烂的日子》,马小军把书包扔上天,书包往天上飞,越飞越高,落下来的时候,上小学的马小军已经变成上中学的马小军。文字也可以这样自由,回忆的纳博科夫看到爸爸被扔到空中,也看到爸爸的葬礼,两个场景叠化在一起,我们的头脑中时常会出现这样的叠化,所以也不难理解纳博科夫的这种写法。

哈代那种写法很古典,纳博科夫这种写法更自由,这两段文字都是在引导读者去想象画面,都希望你在进行想象的时候,不只想到画面,还要想到更多。哈代会说,想象一下夕阳,想象一下宫廷墙壁上的美人,想一想阳光刻画的影子。纳博科夫会说,想一下出生之前死亡之后的深渊,他在文章开头写到婴儿车,在文章结尾写到葬礼,他让被抛向空中的父亲停留在天空中。

文字是很有力量、不受约束的,但是,你得有耐心,去仔细琢磨词句之间那种自如的转换与衔接,并且动用你的想象力。你读到的,会比你看到的更多。

From #

文学体验三十讲