2011-08-25 61 views
14

我正在使用bash腳本在/ tmp /中使用文件的名稱創建一個新文件夾,然後將該文件複製到該文件夾​​中。基地名稱與空格在bash腳本中?

#!/bin/bash 

MYBASENAME="`basename $1`" 
mkdir "/tmp/$MYBASENAME" 

for ARG in "[email protected]" 
    do 
     mv "$ARG" "/tmp/$MYBASENAME" 

done 

行爲:

當我mymove "/home/me/downloads/my new file.zip"鍵入它顯示了這個:

mkdir /tmp/my 
new 
file.zip 
mv: rename /home/me/downloads/my new file.zip to /tmp/my\nnew\nfile.zip: 

我有很多周圍的一切報價,所以我不明白這是爲什麼不按預期工作。

另外,如果有多個文件,我在那裏有表單循環。我想根據第一個參數的基本名稱將它們全部複製到同一個文件夾中。

回答

12

如果賦值是單個命令替換,則不需要引用命令替換。 shell不會爲變量賦值執行分詞。

MYBASENAME=$(basename "$1") 

是所需要的。你應該養成使用$(),而不是反引號的習慣,因爲$()巢更容易(這是POSIX,順便說一句,和所有現代化的炮彈支持。)

PS:你應該儘量慶典腳本。嘗試編寫shell腳本。不同之處在於沒有bashisms,zshisms等。就像C一樣,可移植性是腳本的一個理想特性,特別是如果它可以輕鬆實現的話。你的腳本不使用任何bashisms,所以我會寫#!/bin/sh。對於挑選者:是的,我知道,舊的SunOS和Solaris /bin/sh不明白$(),但/usr/xpg4/bin/sh是POSIX shell。

+0

我注意到很多默認的shell腳本使用sh而不是bash。我仍然無法分辨出太多差別,除了像echo \ c這樣的東西來保持新行不出現。感謝您的提示和有用的答案。 – cwd

+0

使用echo \ c的便攜方式是使用'printf',您只需在格式字符串中省略'\ n'。最經常使用的bashisms可以說是使用了數組變量,非POSIX語法(例如'[[...]]'用於測試,用於for((...))'的循環以及'select'構造。 – Jens

+0

這不適用於在我的macosx獅子(GNU bash,版本3.2.48(1) - 發佈(x86_64-apple-darwin11) – rjha94

4

的問題是,在$1

MYBASENAME="`basename $1`" 

沒有加引號。使用這個來代替:

MYBASENAME="$(basename "$1")" 
+2

+1使用$()形式的命令替換。除非你真的確信你會使用只有Bourne shell的系統,爲什麼不把你的技術語法升級到1993年的標準;-)!我敢打賭你沒有考慮過就使用'sed -i'。但是,在依賴bourne shell或100個其他gnu/linux-isms的系統上,您不會找到'sed -i'。祝你們好運。 shellter

0
MYBASENAME="`basename $1`" 

應該

MYBASENAME="`basename "$1"`" 

包裹$1用雙引號"$1"

2

你錯過了一組引號!

MYBASENAME="`basename \"$1\"`" 

這將解決您的問題。

+0

你正在寫一對引號和反斜槓:-) – Jens