2010-03-04 231 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