2010-03-04 149 views
2

我想编写一个非常简单的脚本,它采用一个进程名称,并返回包含进程名称的最后一个文件名的尾部。Shell脚本 - Linux

我写了这样的事情:

#!/bin/sh 
tail $(ls -t *"$1"*| head -1) -f 

我的问题:

  1. 我需要的第一线?

  2. 为什么不是ls -t *"$1"*| head -1 | tail -f工作?

  3. 有没有更好的方法来做到这一点?

+0

脚本“返回”其状态 - 成功为零,失败为非零。你想要它的“输出”是一个文件名。这是一个重要的区别。 – 2010-03-04 17:10:37

+0

http://mywiki.wooledge.org/ParsingLs – 2010-03-05 11:20:19

回答

6

1:第一行是一个所谓的认领,阅读说明here

在计算,一个认领(也称为 hashbang,hashpling,磅的一声,或 crunchbang)指字符 “#!”当他们是第一个 作为文本文件的第一行时,第一个两个 字符在解释器指令 。在一个 类Unix操作系统, 程序加载器需要的 这两个字符的存在作为指示 该文件是一个脚本,并试图 使用由 的其余部分指定的 解释器来执行该脚本文件中的第一行

2:tail不能从stdin取文件名:它可以将stdin上的文本或文件作为参数。请参阅man page

3:没有更好的解决方案出现在我的脑海中:请注意包含空格的文件名:这不适用于您当前的解决方案,您需要在$()块附近添加引号。

+0

你的意思是“2.' tail'”有没有机会? – 2010-03-04 15:53:32

+0

是的,奇怪的标记错误,有时我不明白标记! – theomega 2010-03-04 15:55:49

+0

好的,但第一行是强制性的吗?无论如何,我将运行该脚本的shell将运行该脚本。我从shell运行脚本。 所以我的问题是我需要什么第一行? – Idan 2010-03-04 16:12:37

2

$1包含第一个参数,进程名实际上是$0。然而,这可能包含路径,所以你应该使用:

#!/bin/sh 
tail $(ls -rt *"`basename $0`"*| head -1) -f 

您还可以使用ls -rt首先得到最旧的文件。

+0

尽管在问题“含有进程名称的文件名称中包含进程名称”我将其解释为“采用包含THAT进程名称的进程名称文件名”所以它是$ 1而不是$ 0我们引用。 – conny 2010-03-04 16:45:13

+0

哎呀,你是对的 - 不知何故我重读了第一部分... – 2010-03-05 09:31:14

0

继@ @ theomega的回答和@Idan在评论中提出的问题之后,除了别的以外,还需要she-bang,因为有些UNIX/Linux系统有多个命令shell。

每个命令shell都有不同的语法,所以she-bang提供了一种方法来指定应该使用哪个shell来执行脚本,即使您没有在运行命令中指定它(例如)

./myscript.sh 

,而不是

/bin/sh ./myscript.sh 

注意,她爆炸也可以在写在非外壳语言,如Perl脚本中使用;在这种情况下,您可以将

#!/usr/bin/perl 

置于脚本的顶部。

+1

呃,* bash *是“Bourne再次壳”。 * sh *通常是其他shell的链接,如* dash *(Debian Almquist shell)或* bash *(尽管* sh *实际上是Solaris上的Bourne shell)。 – 2010-03-04 16:56:42

+0

根据克里斯的评论编辑 - 谢谢,我纠正了。 – 2010-03-05 05:18:51

0

如果从shell运行脚本,则可以省略shebang,在这种情况下,内容将由当前shell实例执行。在很多情况下,这不会造成任何问题,但这仍然是一种不好的做法。

+0

这取决于你如何运行脚本。如果你说'sh/path/to/script',那么shbang就不需要了。如果你说'/ path/to/script',那么最好包含一个shebang,即使你只是从另一个shell运行它。 – 2010-03-04 16:59:49