私はこのようなディレクトリ構造を持っていました:
ravikumar@ravikumar-RV409-RV509-RV709:~$ tree test
test
|
├── 1
├── 2
├── 3
├── 4
├── a
├── b
└── c
mvコマンドを次のように実行しました
ravikumar@ravikumar-RV409-RV509-RV709:~$ cd test/
ravikumar@ravikumar-RV409-RV509-RV709:~/test$ mv *
結果:
ravikumar@ravikumar-RV409-RV509-RV709:~/test$ tree
.
|
└── c
├── 1
├── 2
├── 3
├── 4
├── a
└── b
私の質問は、mv judgeがすべてのディレクトリとファイルを最後のディレクトリにどのように移動するかです。そしてそれはc
です。
そのディレクトリで実行した場合、mv *
はmv 1 2 3 4 a b c
と同等でした。 -t
オプションが存在しない限り、mv
は最後の非オプション引数を宛先の名前として扱い、したがって1
、2
、3
、4
、a
、およびb
allを移動しますc
に。
シェル は、*
をファイル名のリストに展開します。この場合、実行中のコマンドには実際には*
が表示されず、展開されたもののみが表示されます。 したがって、実行するコマンドはcannotは、実際に入力した内容に基づいて引数を処理する方法について判断します。シェルが渡すものだけが表示されます。
mv *
を実行すると、おそらく推測されるように、ほとんど常に回避する必要があります。Shellとnotは、mv
コマンド自体が*
を アルファベット順に展開します 名前が.
で始まるものを除く、現在のディレクトリに含まれるすべてのファイルとディレクトリのリスト。
(dotglob
、nullglob
、およびnocaseglob
シェルオプションとGLOBIGNORE
変数を使用して、その動作をカスタマイズできます。詳細については、 ドキュメントを参照してください )
c
がディレクトリでない場合、コマンドは失敗し、何も移動せず、次のエラーメッセージが表示されます。
mv: target 'c' is not a directory
ただし、c
はディレクトリであるため、コマンドが実行されるのを確認する以外の目的でコマンドを実行している場合でも、おそらくコマンドの最後に別のディレクトリの名前を書きますafter the *
。
mv
がその引数が*
から展開されたことを知る方法がない理由をより直感的に示すために、次のように書いたと仮定します。
mv 1 c
それは1
をc
に移動します。ただし、2つのアイテムをc
に移動したい場合があります。
mv 1 2 c
または5つのアイテム:
mv 1 2 3 4 a c
または6つのアイテム:
mv 1 2 3 4 a b c
ただし、シェルはmv *
が同じ順序でまったく同じ引数をmv
コマンドにmv 1 2 3 4 a b c
として渡すようにしました。
mv
の1回の呼び出しで複数のアイテムを移動できないのは、多くの場合不便です。ただし、これが許可されず、常にエラーが発生した場合でも、2つのエントリのみが含まれるディレクトリで、同様に混乱する状況を作成できます。その後、そのディレクトリでmv *
を実行すると、一方を他方に移動しようとします。
シェルが何を展開するのか疑問に思っている場合は、実行したいコマンドをprintf '%s\n'
に置き換えることができます。これは、その後に渡されるすべての引数を改行で区切って出力します。例えば:
printf '%s\n' *
この答えはいくつかのヒントを追加しています(しかし、主な答えは@Eliah Kaganによるものだと思います)。
物事を少し安全にするために、2つのエイリアスを作成しました。他のエイリアスの近くの~/.bashrc
に保存します。
alias mv='mv -i'
alias rm='rm -i'
これらのエイリアスはコマンドをインタラクティブにし、上書き/削除するかどうかを尋ねます。
mv
は、ターゲットを上書きするか、ターゲットが存在してファイルであるか、ターゲットがディレクトリで、同じ名前のファイルがすでに存在するかどうかを尋ねます。これは、たとえばワイルドカードmv *
を使用する場合など、間違いを避けるのに役立ちます。
気づいてください
これらのエイリアスは、独自のユーザーIDでのみ機能します。 Sudo
では機能しません。 Sudo
の後にエイリアスを展開する場合は、 個別に設定する にする必要があります。ルートシェルで特定のエイリアスを使用する場合(Sudo -s
またはSudo -i
から取得する場合)、同様のエイリアスを作成して/root/.bashrc
に保存する必要があります。
エイリアスをオーバーライド(およびmv
およびrm
の元の動作を取得)するには、プレフィックス 'backslash`を使用します。
\rm filename
\mv filename1 filename2
-i
フラグが自動的に渡されることに慣れて、誤った安全感を持つことがあります。たとえば、別のシステムを実行している場合、これらのエイリアスはアクティブではありません。