2013-02-01 64 views
1

如果我運行此命令它工作在終端罰款:命令終端而不是通過/ bin中運行/ SH

for dirname in $(ls -d dir/checkpoint/features.txt/20*);do;echo "hello";done 

但是,當通過/ bin/sh的運行-c它給出了一個錯誤

/bin/sh -c "for dirname in $(ls -d dir/checkpoint/features.txt/20*);do;echo "hello";done" 

錯誤:

/bin/sh: -c: line 1: syntax error near unexpected token `dir/checkpoint/features.txt/201108000' 
/bin/sh: -c: line 1: `dir/checkpoint/features.txt/201108000' 

我的默認的shell /斌/慶典。我似乎無法理解是什麼導致了這一點。在我的程序中運行所有shell命令的默認實現是通過給它們添加/ bin/sh -c。這是我第一次看到這個問題。有什麼建議麼?

+0

試圖逃跑像字符」 * ... – fedorqui

+0

是'/斌/ sh'一樣'/bin/bash'?在Solaris的舊版本上,例如'/ bin/sh'不是POSIX shell,並且不能識別'$(...)'表示法。你是否嘗試用單引用 –

+1

由於您已經添加了另一組雙引號,因此sh不會像您認爲的那樣解析它,而是在外部使用單引號 – chris

回答

2

不要試圖解析ls的輸出,尤其是for構造。有很多方法可能會出錯。

這是一個使用find代替的好地方。試試這個:

/bin/sh -c "find dir/checkpoint/features.txt -mindepth 1 -maxdepth 1 -type d -iname '20*' -exec echo \"hello\" \;" 

而且消除了容易出錯的使用ls,您避免的問題,子shell和所有它所帶來。

後續響應您的評論:

我假設你使用awk -F/ '{print $NF}'抓住文件夾的名稱在文件生命(也就是文件名前的最後一個目錄名)。命令basenamedirname可以用來爲你做這個。這應該使你的腳本更容易一些。將以下到一個腳本文件:

#!/bin/sh 
folder=$(basename $(dirname $1)) 
mkdir -p #{nfs_checkpoint}/${folder} 
cat #{result_location}/${folder}/20* > #{nfs_checkpoint}/${folder}/features.txt 

並執行這樣的:

/bin/sh -c "find dir/checkpoint/features.txt -mindepth 1 -maxdepth 1 -type d -iname '20*' -exec yourscript.sh {} \;" 
+1

切換到外部的單引號會更清楚,而不是試圖逃避內部雙引號。 '/ bin/sh -c'foo「bar」'''而不是'/ bin/sh -c「foo \」bar \「」'。 –

+0

感謝您的回答!那麼只是爲了簡單起見,我在問題中粘貼了這樣的命令,但真正的命令是'for $(ls -d#{result_location}/20 * | awk -F /'{print $ NF}'')中的dirname。 ; do; mkdir -p#{nfs_checkpoint}/$ {dirname}; cat#{result_location}/$ {dirname}/20 *>#{nfs_checkpoint}/$ {dirname} /features.txt; done'。我主要掙扎的是如何通過查找 – shaurya

+0

'ls -b'來獲取文件名(而不是文件路徑)。至少對於GNU用戶的土地。但是,我也更喜歡'find',並將其轉換爲'while read' ... – 0xC0000022L

相關問題