bugfix> bash > 投稿

bashスクリプトでのファイルの移動に問題があります。 私はここで見つけたさまざまな解決策を同じ問題について試してきましたが、うまくいくものを見つけることができません。

私の最後の試みは追加でした shopt -s dotglob nullglob しかし、それは何も解決しませんでした。

このテストでは、

jdir0="/media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)"

mv -v "$jdir0/*" "$jdir0/subs/" &>> $debuglog

..そして私は得る:

mv: cannot stat '/media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/*': No such file or directory

しかし、はい、あります!

drwxrwx--- 1 root vboxsf   4096 Aug 22 07:06  ../
-rwxrwx--- 1 root vboxsf      0 Aug 21 17:19 'kallee.(222)..nnn.srt'*
-rwxrwx--- 1 root vboxsf 159363 Aug 21 17:26 'movie.test(2929).ismim.mp4'*
drwxrwx--- 1 root vboxsf      0 Aug 22 07:06  subs/

(名前が本当に奇妙なのは、この関数の前に無効な文字を削除するためにテストしているからです)

更新:どうやら断続的なエラーが発生したようで、数日後にようやくサーバーの問題(ファイルが保存されている場所)までさかのぼります。 どうやらこれらのエラーは、サーバーが保存/名前の変更を完了しておらず、スクリプトが何か新しいことをするように要求した場合に発生しました。 たとえば、ファイルAの名前をBに変更し、サーバーが最初の要求を実行する前にBをCに名前変更するように要求すると、サーバーは次のように述べました。

回答 1 件
  • * シェルのグロブ演算子です。そのように認識されるように、引用符で囲まないでおく必要があります。引用すると /media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/* 文字通りに渡されます mv そして mv というファイルを移動しようとします * 、そのようなファイルはありません。

    だからあなたは必要です:

    mv -v -- "$jdir0"/* "$jdir0/subs/" >> "$debuglog" 2>&1
    
    

    シェルが拡張するために "$jdir0"/* 呼び出す前に一致するファイルのリストに mv

    あなたがやるない欲しいです nullglob これは、それに一致するファイルがない場合に "$jdir0"/* パターン、 mv だけで呼び出されます -v-- そして media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/subs/ によって混乱する構文エラーを引き起こします mv

    failglob グロブが一致しないときにコマンドを中止することは、その場合にはより良いオプションかもしれませんが、 bash その場合、コマンドが呼び出されたコンテキストに応じて、一貫性のない方法でアボートするため、スクリプトでそのオプションを使用するのは難しいです。

    dotglob グロブが隠しファイルと一致できるようにすることです。

    ここで、グロブはタイプに関係なくファイルに一致することに注意してください¹、 * 上記も一致します subs 。もし subs ディレクトリへのシンボリックリンクです。 mv 喜んでそれを動かします subs そのディレクトリへのシンボリックリンクにより、以降のすべての移動が subs ターゲットディレクトリはなくなりました。もし subs プレーンなサブディレクトリです。 mv ディレクトリをそれ自体に移動できないと文句を言うでしょう。

    そのため、代わりにそれを書きたいと思うかもしれません:

    shopt -s extglob
    mv -v -- "$jdir0"/!(subs) "$jdir0/subs/" >> "$debuglog" 2>&1
    
    

    どこ !(pattern) 実行するすべてのファイル名に一致するksh拡張glob演算子ですない一致 pattern なので、ここではファイルを移動しますが、 subs

    また、 bash シェルでは、非対話型シェルインスタンス(bashがPOSIXモードの場合を除く)でも、リダイレクトのターゲットにある場合、パラメーター展開を引用符で囲む必要があります。


    b bashの代わりにzshとそのグロブ修飾子を使用しない限り *(.) 移動するだけ定期的ファイル

あなたの答え