web-dev-qa-db-ja.com

bashスクリプトにスペースを含むベース名?

ファイルの名前を使用して/ tmp /に新しいフォルダーを作成し、そのフォルダー内にファイルをコピーするbashスクリプトに取り組んでいます。

#!/bin/bash

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

for ARG in "$@"
    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:

私はすべての周りにたくさんの引用符があるので、なぜこれが期待どおりに機能しないのか理解できません。

また、複数のファイルがある場合に備えて、そこにフォームループがあります。最初の引数のベース名に基づいて、それらすべてを同じフォルダーにコピーする必要があります。

19
cwd

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

_MYBASENAME=$(basename "$1")
_

必要なのはそれだけです。 $()はネストしやすいため、バッククォートの代わりに$()を使用する習慣を身に付ける必要があります(POSIXですが、最近のすべてのシェルでサポートされています)。

PS:not write bashスクリプトを試してみてください。 シェルスクリプトを書いてみてください。違いは、bashisms、zshismsなどがないことです。Cの場合と同様に、移植性は、特に簡単に実現できる場合、スクリプトの望ましい機能です。スクリプトはバシズムを使用していないので、代わりに_#!/bin/sh_と記述します。ニットピッカーの場合:はい、わかっています。古いSunOSとSolaris _/bin/sh_は$()を理解していませんが、_/usr/xpg4/bin/sh_はPOSIXシェルです。

18
Jens

問題はそれです $1 in

MYBASENAME="`basename $1`" 

引用されていません。代わりにこれを使用してください:

MYBASENAME="$(basename "$1")"
4
Ulrich Dangel

一組の引用符がありません!

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

それはあなたの問題を解決します。

2
Carl Norum
MYBASENAME="`basename $1`"

する必要があります

MYBASENAME="`basename "$1"`"

$1を二重引用符で囲みます"$1"

0
phoxis