2010-01-07 15 views
0

我是shell腳本的新手。csh與bash不同的地方是* NAME * patten到文件列表

我注意到,像命令:

tar cf test.tar *TEST* *TEST2* 

sh和bash將擴大TEST到文件名列表,而CSH不會。 我希望shell不要花費,我該怎麼做?

使用「或」會導致其他問題,如果有文件匹配模式* TEST *,但沒有文件匹配* TEST2 *, 那麼焦油會失敗。

[編輯]我認爲這是bash和CSH之間的花費差異。 如果沒有模式發現* TEST *,CSH將耗費爲「」,而bash將花費爲「TEST」(加引號字符)。

+0

使用引號:''* TEST * '* TEST2 *'',' 「* TEST *」, 「* TEST2 *」',或者使用反斜線:'\\ * TEST \\ * \\ *。 TEST2 \\ *'。 – 2010-01-07 09:03:44

+0

這不起作用。 tar:* TEST *:不能stat:沒有這樣的文件或目錄 tar:錯誤退出延遲以前的錯誤 – 2010-01-07 09:09:45

回答

2

man bash

如果選擇了nullglob設置,並沒有 找到匹配,這個詞是 刪除。

例如:

betelgeuse:TEST james$ touch TEST1 TEST3 
betelgeuse:TEST james$ ls *TEST* *TEST2* 
ls: *TEST2*: No such file or directory 
TEST1 TEST3 
betelgeuse:TEST james$ shopt -s nullglob 
betelgeuse:TEST james$ ls *TEST* *TEST2* 
TEST1 TEST3 

這大約相當於csh行爲:

[betelgeuse:/tmp/TEST] james% ls *TEST* *TEST2* 
TEST1 TEST3 

的區別在於csh將返回一個錯誤的文件名模式的如果所有一條線不能匹配任何東西:

[betelgeuse:/tmp/TEST] james% ls *TEST4* *TEST2* 
ls: No match. 

bash只返回令牌的列表的命令,導致古怪像這樣:

betelgeuse:TEST james$ ls *TEST4* *TEST2* 
TEST1 TEST3 

*TEST4**TEST2*都返回什麼;所以ls命令認爲它已被調用,沒有參數,只給出了目錄的列表。在你的例子中,焦油會(正確)抱怨它沒有被處理的文件。

+0

酷!有沒有一個標準的方式爲這個問題的所有POSIX標準平臺?謝謝。 – 2010-01-07 09:28:07

+0

POSIX合規性,ey?現在你變得棘手.. – 2010-01-07 09:32:37

+0

我在solaris找到了sh,不支持shopt ... – 2010-01-07 09:36:13

0

包括在單串報價:

tar cf test.tar '*TEST2*' 
+0

使用''會導致tar的其他問題(如果* TEST2 *找不到匹配項)。但沒有',csh運作良好。 – 2010-01-07 09:05:41

+0

你的文件名是否有星號,或者你想要做什麼? – JesperE 2010-01-07 09:18:38

0

戴上*成單引號,即'*'

1

附上你的論點在單引號或轉義:

tar cf test.tar '*TEST*' '*TEST2*' 

tar cf test.tar \*TEST\* \*TEST2\* 
0

如回答別人,眼前的解決辦法是把*在單引號字符串中或用反斜槓轉義。

無論如何,在文件名中使用星號但不禁止,這是一個非常糟糕的主意。

+1

我其實想要一個patten匹配。不是文件名中的星號。 – 2010-01-07 09:18:44

2

試試這個

shopt -s nullglob 
tar cf test.tar *TEST* 2>/dev/null 

版本的Solaris自帶的bash了。所以你可以嘗試使用bash。如果你的Solaris版本沒有bash,我想你只需要以「更長」的方式來做。

for file in *TEST* 
do 
    tar uf test.tar "$file" 
done