外部から呼び出されたときにスクリプトが機能しない


8

単純なスクリプトを使用して、.mp4ファイルから.mp3を作成します。

#!/bin/bash
for i in *.mp4
do
ffmpeg -i "$i" -ab 128k "${i%mp4}mp3"
done

スクリプトは、デスクトップから実行するか、ターミナルから呼び出すと正常に実行されます。ただし、スクリプトが外部スクリプトから呼び出されると、実行に失敗し、

「* .mp4:そのようなファイルまたはディレクトリはありません」。

問題はシェル拡張にあると思われますが、この状況でそれを修正する方法に頭を抱えることはできません。

回答:


13

相対パスを使用していて、スクリプトが.mp4現在のディレクトリ(スクリプトが実行されているディレクトリ)で.mp4ファイルを探しており、そのようなファイルが存在しないことがわかった場合、リテラル*.mp4ファイルを探します(nullglob/ failglobがセット、これがデフォルトです)、そのファイルも存在しないため、エラーメッセージが表示されます*.mp4: No Such File or Directory

代わりに絶対パスを使用する必要があります。

for i in /directory/*.mp4; do ...; done

/directory/実際のディレクトリパスに置き換えます。必要に応じて、最初の引数としてディレクトリ名も使用できます。

for i in "$1"/*.mp4; do ...; done

ここでは絶対パスまたは相対パスを使用できますが、ここでも絶対パスが常に安全なオプションです。

次に、通常の方法で実行可能スクリプトを呼び出します。

/path/to/script.sh /directory

スクリプトディレクトリから:

./script.sh /directory

助けてくれてありがとう。私はすでにそれをうまくいかなかったと伝えようとしていましたが、最初に "/ home"の "H"を大文字にしたことに気付きました。引数としてパスを渡すことは特に役に立ちました。乾杯。
M. Street

ここで「エラーメッセージが表示される」とは、実際にはシェルが*.mp4どのファイルにも一致しないため、リテラルファイル名と見なし、呼び出されたファイル*.mp4(有効なファイル名)を開こうとし、ファイルがないために失敗することを意味します。呼ばれる*.mp4現在のディレクトリでれます。*.mp4空の可能性がある一致するファイル名のリストに常に展開すると考える人もいるforでしょう(その場合、ループは何もせず、エラーは発生しません)。これは*.mp4当てはまりません。常に何かに展開されます。
バクリウ2017年

@Bakuriuこれは、この場合(または bash)にが、常にそうとは限りません。nullglob/を見てくださいfailglob
heemayl 2017年

'*'はパスとファイル名の組み合わせではなく、ファイル名だけであると誤解していました。生きて学ぶ:)
M. Street
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.