実行するには、コンソールに次のコマンドを直接入力します。
[root@server user]# curl -d 'parameter=170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
一方、bashスクリプトがありますaddinfo.sh
。
#!/bin/bash
tail -n0 -F info.txt | while read LINE; do
ins="curl -d 'parameter=$LINE' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add"
echo $ins
$ins
done
その後、次のechoコマンドを実行すると、出力がkeepとして表示されます。
[root@server user]# echo '170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' >> info.txt
[root@server user]# curl -d 'parameter=170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
curl: option -: is unknown
curl: try 'curl --help' or 'curl --manual' for more information
HTTP 要求は実行されませんでした。次の入力データは変更できません。
170.22.16.14 192.10.2.24 - - [01/Jan/1900:00:00:00 -0300] "GET /files/notes.txt HTTP/1.1" 200 112061 "-" "Java/1.8.0.160"
それでは、Bashスクリプトを変更するにはどうすればよいですか?
ベストアンサー1
ins="curl -d 'parameter=$LINE' -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add"
変数に入力するのはシェル構文です。これは、シェルが解析するシェルコマンドラインに(対話式またはスクリプトとして)入力するコマンドの形式です。
$ins
ただし、これはシェル構文の変数の内容を解析しません。代わりに、トークン化とワイルドカードを値に適用し、結果フィールドをコマンド名と引数として使用します。これは、引用符、演算子(リダイレクトを含む)、または拡張(ドル記号またはバックティックを含む)などの構文要素を処理するのとは異なります。
ここでは、コマンド名とパラメータcurl
、、、、、などが生成されます。-d
'parameter=170.22.16.14
192.10.2.24
-
-
そこにある難しい引用を参照してください。これは、シェルコマンドを実行したときに得られるのと同じ結果です。
curl -d "'parameter=170.22.16.14" 192.10.2.24 - - etc.
原則の根本的な違いは、変数に次のものを含める必要があることです。データ、データはコードに解析されません。引用符を使用する場合は、このように機能したい場合がありますが、これは、たとえば、すべてのコマンド置換返品たとえば、コマンドライン引数またはファイル名に実行などの文字列が表示されることがあります。合理的な方法で任意の文字列を処理することは不可能です。
正確に言えば、データにコードを入れないで直接コマンドを実行してください。
tail -n0 -F info.txt | while read LINE; do
curl -d "parameter=$LINE" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
done
または、必要に応じて、まずコマンドを関数に保存します。
f() {
curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
}
tail -n0 -F info.txt | while read LINE; do
f "$LINE"
done
実行中のコマンドを印刷するには、set -x
シェルを使用して実際に実行された内容を印刷できます。 (Bashはシェル入力として再利用するのに適した明確な形式でこれを行います。他の形式はあいまいな出力を生成できます。)
上記の関数を修正してください:
f() (
set -x
curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add
)
または、コマンド全体を配列に保存して印刷してから実行できます。 (しかし、これはあいまいな出力を提供します):
f() {
cmd=(curl -d "parameter=$1" -H 'Content-Type: application/x-www-form-urlencoded' -X POST http://192.138.1.10:8080/system/add)
printf "%s " "${cmd[@]}"
echo
"${cmd[@]}"
}