私は次の問題にぶつかりました:私は次のことを行うLinuxbashスクリプトを書いています:
\n
文字を削除します例:commands.txt
ls
ls -l
ls -ltra
ps as
Bashファイルを実行すると、最初の行が取得されて実行されますが、\n
が存在する間、シェルは「command not found:ls」を出力するだけです。スクリプトのその部分は次のようになります。
read line
if [ -n "$line" ]; then #if not empty line
#myline=`echo -n $line | tr -d '\n'`
#myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`
myline=`echo -n $line | tr -d "\n"`
$myline #execute it
cat $fname | tail -n+2 > $fname.txt
mv $fname.txt $fname
fi
SOに尋ねる前に私が試したことがあるとコメントしました。解決策はありますか?私はこれで最後の数時間脳を壊しています...
改行をトリミングするために、私は常にPerl -ne 'chomp and print'
が好きです。素晴らしく、覚えやすい。
例えばls -l | Perl -ne 'chomp and print'
ただし
それがここでのあなたの問題ではないと思います。ファイル内のコマンドをシェルスクリプトの「読み取り」に渡す方法がわかりませんが。
このような私自身のテストスクリプト(test.sh)
read line
if [ -n "$line" ]; then
$line
fi
そしてこのようなサンプル入力ファイル(test.cmds)
ls
ls -l
ls -ltra
この./test.sh < test.cmds
のように実行すると、期待される結果が表示されます。これは、現在の作業ディレクトリで最初のコマンド「ls」を実行することです。
おそらく、入力ファイルに追加の印刷不可能な文字が含まれていますか?
私のはこのように見えます
od -c test.cmds
0000000 l s \n l s - l \n l s - l t
0000020 r a \n
0000023
以下のコメントから、入力ファイルにキャリッジリターン( "\ r")が含まれている可能性があります。これは改行と同じではありません。入力ファイルは元々DOS形式ですか?その場合、期待される結果を得るには、「\ r\n」で終わる2バイトのDOS行を1バイトのUNIX行「\ n」に変換する必要があります。
コメントアウトされた行のいずれかで「\ n」を「\ r」に交換することで、これを実行できるはずです。
誰かがすでにシェルコマンドを実行するプログラムを書いています:shファイル
本当にファイルの最初の行だけを実行したい場合:head -n 1 file |sh
問題がキャリッジリターンの場合:tr -d '\r' <file |sh
私はこれを試しました:
read line
echo -n $line | od -x
入力「xxxx」の場合、次のようになります。
0000000 7878 7878
ご覧のとおり、変数の内容の最後に\n
はありません。オプション-x
(bash -x script
)を指定してスクリプトを実行することをお勧めします。これにより、実行時にすべてのコマンドが出力されます。
[編集]あなたの問題は、Windowsでcommands.txtを編集したことです。現在、ファイルには、read
を混乱させる行区切り文字としてCRLF(0d0a)が含まれています(また、ls\r
は既知のコマンドではありません)。 dos2unix
などを使用して、Unixファイルに変換します。
Bashビルトインのみを使用して、キャリッジリターンを改行に置き換えることもできます。
line=$'a line\r'
line="${line//$'\r'/$'\n'}"
#line="${line/%$'\r'/$'\n'}" # replace only at line end
printf "%s" "$line" | Ruby -0777 -n -e 'p $_.to_s'
evalコマンドが必要です
#!/bin/bash -x
while read cmd
do
if [ "$cmd" ]
then
eval "$cmd"
fi
done
私はそれを実行しました
./ script.sh <file.txt
そしてfile.txtは:
ls ls -l ls -ltra ps as
ls
では機能しませんが、 find
の-print0
オプションを確認することをお勧めします
次のスクリプトは機能します(少なくとも私にとっては):
#!/bin/bash
while read I ; do if [ "$I" ] ; then $I ; fi ; done ;