web-dev-qa-db-ja.com

.shスクリプトで実行する複数の引数を渡す方法

ログファイルのリストを含むlist.txtファイルがあります。

例えば

    server_log1
    server_log2
    ........
    server_log50

これらのログのダウンロードに使用する別のシェルスクリプトがあります。それはこのように働きました

./script.sh serverlog1

私はそれを自動的に作成したいと思います。つまり、実行する各ログファイルの名前をlist.txtで自動的に渡すことができます。

それは可能ですか?私は試した

#!/bin/bash
for i in `cat /home/ec2-user/list.txt` ; do
sh ./workaround.sh $i
done

しかし、それはうまくいきませんでした

4
The One

引数を読み取る最も簡単な方法は、次のように説明できます。

各引数は、$IFSまたは現在定義されているinternal file separatorによって参照および解析されます。デフォルトの文字はスペースです。

たとえば、次のようにします。 # ./script.sh arg1 arg2

この例の引数リストはarg1 = $1arg2 = $2で、arg1 arg2 = $@に書き換えることができます。

もう1つの注意点は、ログのリストの使用です。どのくらいの頻度で変更されますか?私の仮定は毎日です。ディレクトリ出力を反復ループの配列として使用しないのはなぜですか?例えば;

for i in $(ls /path/to/logs); do
  ./workaround.sh $i;
done

さらに良いことに、bashでfunctionsを使用して混乱を解消します。

function process_file()
{
  # transfer file code/command
}

function iterate_dir()
{
  local -a dir=($(ls $1))
  for file in ${dir[@]}; do
    process_file $file
  done
}

iterate_dir /path/to/log/for

これらはシェルスクリプトの知識を向上させるための提案にすぎませんが、エラーが発生しているかどうかを知る必要があり、各スクリプトのコードや機能の詳細も知っておく必要があります。 -x引数を使用すると、スクリプトのデバッグにも役立ちます。

ログを転送するだけの場合は、スクリプトをすべて取り除き、rsyncrsyslogまたはsyslogを使用することをお勧めします。問題のタスク。

4
jas-

スクリプト内:行を$ REPLY変数として扱うには、while read ; do ......... ; done < filenameのような読み取りループが必要です...

例えば

while read 
do
mv $REPLY $REPLY.old
done < liste.txt

liste.txt内のファイル名をfilename.oldに変更します

これで構造が整いました。list-txt内の各ログファイル名の"が意味する内容に応じて、実行する必要があります。" :)

2
francois P
xargs -n 1 ./script.sh <list.txt

この例では、xargsは、標準入力から読み取られた単一の引数で./script.shを複数回実行します。

標準入力は、単純なシェル入力リダイレクトを介してlist.txtファイルから取得されます。これは、list.txtファイルに、スクリプトで使用する引数が1行に1つ含まれていることを前提としています。

./script.shスクリプトは、list.txtファイルの行ごとに1回実行されます。


xargsへの-nフラグについて

-n number

tilityを呼び出すnumber(正の10進整数)の最大引数まで、可能な限り多くの標準入力引数を使用します。


別の解決策は、スクリプトがlist.txtから直接読み取るか、複​​数のコマンドライン引数(list.txtからのエントリ)を取り、ファイルを1つまたは複数のバッチでダウンロードすることです。しかし、スクリプトの仕組みがわからないので、これを実行する方法を詳しく説明することはできません。

2
Kusalananda

注:私は個人的に Kusalanandaのアプローチ がこの特定のシナリオで最高だと思うので、いくつかの説明情報を追加しますと推奨事項)


forで行を読み取らない

そのアプローチを使用すると:

  • Word splitting を使用して機能を動作させます。
  • globbing のような意図しない副作用の影響を受けます。
  • ファイル全体を一度にメモリに投入します(大きなファイルでは問題になる場合があります)。

while + readアプローチが推奨されますが、 これは防弾ソリューションではありません

_while IFS= read -r line; do
  # Your code here
done < file
_

変数を引用する

_"$i"_の代わりに_$i_を記述します。引用符で囲まれていない変数は、おそらくシェルスクリプトのバグとセキュリティホールの主な原因です。

関連する質問:

_`...`_の代わりに$(...)を使用します

$(...)はPOSIXに準拠しており、簡単にネストできます。


スクリプトを変更して、複数の引数と_--batch_オプションをサポートすることもできます。

どこから始めればよいかわからない場合は これらの機能をサポートするサンプル/テンプレートスクリプトがあります (ただし、Bash固有の構文を使用しています)。

使用例:

_$ cat list.txt
list_item_1
list_item_2
list_item_3
$ script --batch list.txt item_1 item_2
Operands:
  1: [list_item_1]
  2: [list_item_2]
  3: [list_item_3]
  4: [item_1]
  5: [item_2]
_
1
nxnev