2017-02-06 1 views
0

ファイルを入力として使用するbashスクリプトを作成しようとしています。スクリプトは通常、スクリプトで宣言されたファイルを持っていればうまく動作しますが、動的変数にしようとすると、そのファイルをスクリプトにドロップすることで破損します。Bashスクリプトは、ファイルまたはディレクトリではないファイルを返します。

#!/bin/bash 

input="$HOME/Desktop/test.txt" 

if [ -f "$input" ]; then 
    echo "is file" 
else 
    echo "is NOT file" 
fi 

リターン:

ターミナルリターンにドロップされたファイル "$ HOME /デスクトップ/ test.txtの" を持つファイル

#!/bin/bash 

read input 

if [ -f "$input" ]; then 
    echo "is file" 
else 
    echo "is NOT file" 
fi 

として

です:

は、私は、ファイルをドロップすることはありませんファイルからそれを変更する理由として明確ではないよ

ファイルではありません。私は無駄に多くのバリエーションを試しました。

+1

*ドラッグアンドドロップ*を意味しますか? – heemayl

+0

'ls -l $ HOME/Desktop/test.txt'の出力を貼り付けてください – codeforester

答えて

1

フィールドをグラフィカル環境でドラッグアンドドロップすると、シェルには文字列に追加文字(引用符など)が含まれている可能性があります。あなたのスクリプトは、シェルが提供するファイル(引用符を含む)を見つけようとしているファイルを見つけようとします。

初期の解決策は - お勧めしますが、それは

あなたはこれを試すことができ、元のポスターのために働いていたので、ここに残っていない:printf文は2つのことを行い

read input 
printf -v input "$(eval echo "$input")" 

こと:それが-v inputを使用しています変数inputに新しい値を割り当てます。それが割り当てる値は、コマンド置換$()でキャプチャされたeval echo "$input"の出力です。 evalコマンドとして実行する前に渡された引数に対して強制的に展開を実行します。コマンドはechoになり、その値は変数inputの(展開された)初期値になります。

覚えておいてください:readあなたが入力したものをそのまま変数に取り込むだけで、拡張または単語分割は実行されません。

evalを使用するとコードインジェクションリスクが発生することに注意してください。特別に細工された値はevalで任意のコードを実行させる可能性があり、私が提案しているコードはそれを保護しません。ターミナルウィンドウに送信される文字列の正確な形式がわかっている場合、より安全で、より良い方法があります。

アップデート - あなたが知っていれば勧告たとえば

オリジナルポスターからの追加の詳細情報をもとに、ファイル名は単一引用符内にある、あなたは(また、先頭と末尾の空白を無視されます)この操作を行うことができます:

read input 
if 
    [[ $input =~ ^[[:space:]]*\'(.*)\'[[:space:]]*$ ]] 
then 
    input="${BASH_REMATCH[1]}" 
fi 

このコードスニペットは、ファイル名がある場合はファイル名を抽出し、それ以外の場合は入力を残し、コードインジェクションの観点からは安全です。

+0

ファイルを端末に落としたときに実際に何が起きているのか誤っているかもしれません。私がドラッグアンドドロップすると、 "/home/user/Desktop/test.txt"のフルパスが端末に表示され、まだ返されません。 あなたのソリューションは私にとってはうまくいくと言いましたが、何か変わったと言いましたか、あるいはどちらかの方法でevalを使う必要がありますか? – nothing

+0

@nothingドラッグ&ドロップ操作で文字列の先頭や末尾に何かが追加されていると思われます(例:キャリッジリターン、スペースなど)。あなたのスクリプトに 'read'の直後に次のコマンドを追加して、それがどのような出力を生成しているかを見てみましょう:' echo " - $ {input} - " '。ダッシュとファイル名の間に奇妙なものや余分な間隔/改行がある場合は、これが問題です。 – Fred

+0

あなたのアドバイスを試してみると、ファイルをドロップするときに、 '/ home/user/Desktop/test.txt'のように出てくる問題があるようです。シェルがファイル名の文字として解釈している可能性があります。 – nothing

関連する問題