ln -sは、変数に渡されるとファイル名の一部を削除します。

ln -sは、変数に渡されるとファイル名の一部を削除します。

ダウンロードしたファイルを他のディレクトリにリンクするスクリプトを使用しています。ファイル名に「-」が含まれていると、変数が使用中のログファイルに正しく書き込まれても、ln -sはパスを正しく読み取れません。

for f in ${AVIFILES}
do
        BaseAviName=$(basename "$f" .avi)
        aviMp4name="'""$targetdir""/""$BaseAviName"".mp4""'"
        linkAviFile="'""$targetdir""/""$f""'"
        downloadedFile=$("'""$theFile""/""$f""'")
        ln -s "$downloadedFile" "$linkAviFile" >>$logPath 2>&1
        echo "fileIs: " "$f" ",linkAviFile is" "$linkAviFile" ",BaseAviName:" "$BaseAviName" '$aviMp4name: ' "$aviMp4name" '$downloadedFile: ' "$downloadedFile" >> "$logPath"   
done

次のエラーメッセージは次のとおりですln

ln: failed to create symbolic link ‘'/home/user/Videos/TVEpisodes/Parks and Recreation/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'’ -> ‘’: No such file or directory

downloadFile変数が正しいパスで書き込まれても:

'/home/user/Downloads/Parks And Recreation - Season 3 - DVDRip-REWARD/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'

何らかの理由で$downloadedFileをlnに拡張して使用すると、lnは最初の "-"から次の "/"までのファイル名の一部を省略するようです( - Season 3 - DVDRip-REWARD ))。これが起こる可能性のある理由を見つけることができず、これを避けたいと思います。どんな提案がありますか?

編集:スクリプトを再構築しましたが、問題は消えました。助けてくれた人に感謝します

答え1

downloadFile変数が正しいパスで書き込まれても:

'/home/user/Downloads/Parks And Recreation - Season 3 - DVDRip-REWARD/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'

これは明らかに正しいパスではありません。'先頭と末尾に追加の文字があります。次のエラーメッセージでこれを確認できますln

ln: failed to create symbolic link ‘'/home/user/Videos/TVEpisodes/Parks and Recreation/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'’ -> ‘’: No such file or directory

'エラーメッセージのファイル名は「一重引用符」内にあり、先頭と末尾に追加(ASCII単一引用符)文字があります。

スクリプトの問題は明らかです。 、およびを'定義するときに追加の文字を追加しました。しないでください。aviMp4namelinkAviFiledownloadedFile

for f in "${AVIFILES[@]}"
do
    BaseAviName=$(basename -- "$f" .avi)
    aviMp4name="$targetdir/$BaseAviName.mp4"
    linkAviFile="$targetdir/$f"
    downloadedFile=$("$theFile/$f")
    ln -s -- "$downloadedFile" "$linkAviFile" >>$logPath 2>&1
    echo "fileIs: " "$f" ",linkAviFile is" "$linkAviFile" ",BaseAviName:" "$BaseAviName" '$aviMp4name: ' "$aviMp4name" '$downloadedFile: ' "$downloadedFile" >> "$logPath"   
done

殻にソース文法、一重引用符で区切られたリテラル文字列(a='hello world!'変数をa12文字の文字列に設定hello world!)、一重引用符を追加する場合変数としてを使用すると、一重引用符が表示されます。 14文字の文字列にa="'hello world!'"設定されます。a'hello world!'

シェルスクリプトで引用符を使用するときに覚えておくべき重要な点は、変数拡張の周りに二重引用符を置くことですln -s -- "$downloadedFile" "$linkAviFile"。このようなコードはln -s -- $downloadedFile $linkAviFile変数値を空白文字downloadedFileに分割しlinkAviFile、各部分をワイルドカードパターンとして解釈します。これらの二重引用符はシェルのソース構文の一部であり、パーサーによって解釈されます。変数の値に引用符を入れても問題は解決しません。

また、ファイル名がで始まる場合、-コマンドはそれをオプションとして解釈します。これを回避するには、変数にファイル名がある場合は、すべてのオプションの後とすべてのファイル名の前に引数をコマンドに渡します。たとえば、ファイル名が次から始まらないことがわかっている場合は、--yesを省略できます。 )絶対パス)。これは、「今後はオプションはありません」を意味します。-----

${AVIFILES}引用符のない他の拡張と同様に、変数の値をスペースで除算します。複数のファイル名を変数に保存するには、文字列の代わりに配列として作成します。これにはksh、bash、またはzshが必要で、通常のshでは機能しません。

AVIFILES=(foo.avi bar.avi "file name with spaces.avi")

関連情報