2011-08-25 5 views
14

私は、ファイルの名前を使って/ tmp /に新しいフォルダを作成して、そのフォルダの中にファイルをコピーするためにbashスクリプトに取り組んでいます。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

割り当てが単一のコマンド置換である場合は、コマンド置換を引用する必要はありません。シェルは変数の代入にワード分割を実行しません。

MYBASENAME=$(basename "$1") 

がすべてかかります。 $()より簡単に巣(。それはところでPOSIX、だし、すべての近代的なシェルがそれをサポートしています。)ので、あなたは$()代わりにバッククォートを使用しての習慣を身に取得する必要

PS:あなたはない書き込みのbashスクリプトに試してみてください。 シェルスクリプトを作成してみてください。違いは、bashisms、zshismsなどがないことです.Cの場合と同じように、移植性はスクリプトの望ましい機能です(特に簡単に達成できる場合)。あなたのスクリプトはbashismsを使用しないので、代わりに#!/bin/shと書いておきます。ニックピッカーの場合:はい、知っています、旧SunOSとSolaris /bin/sh$()を理解できませんが、/usr/xpg4/bin/shはPOSIXシェルです。

+0

多くのデフォルトシェルスクリプトはbashではなくshを使用しています。新しい行を表示しないように 'echo \ c'のようなものを除いて、私はまだ違いをあまり伝えられません。ヒントと役に立つ答えをありがとう。 – cwd

+0

echo \ cを使用する移植可能な方法は、 'printf'を使うことです。書式文字列で' \ n'を省略するだけです。最も頻繁に使われるbashismは、配列変数、テスト用に '[[...]]'のような非POSIX構文、 'for((...)) 'を持つループ、' select'構造体。 – Jens

+0

これは、結果は何ですか?動作しません正確にどのようなrjha94 @(1)-release(x86_64版 - アップル-darwin11) – rjha94

4

問題が$1

MYBASENAME="`basename $1`" 

にはクォートされていないということです。代わりにこれを使用します。

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

+1は、コマンド置換の$()形式を使用しています。あなたが本当に本当に確かにしているのでなければ、ボーンシェルだけを持つシステムを使用していて、あなたのテクノロジーの構文を1993年の標準にアップグレードしてみませんか?私はあなたがそれを考えずに 'sed -i'を使うと確信しています。しかし、あなたは 'sed -i'をbourneシェルや100種類のGNU/Linux-ismsに依存するシステムで見つけられません。皆さんお元気で。 shellter

0
MYBASENAME="`basename $1`" 

MYBASENAME="`basename "$1"`" 

ラップあなたが引用符の1セットが欠落している二重引用符"$1"

2

$1する必要があります!

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

これで問題は解決します。

+0

あなたは一組の引用符とバックスラッシュをあまりにも書いています:-) – Jens

関連する問題