SASコードを一括実行するコマンドの周りにrun_sas.sh
ラッパーがあります。sas
一般的な通貨は次のとおりです。
./run_sas.sh -sysin /my_code/my_program.sas -log /my_log_folder/my_program.log
run_sas.sh
すべてのパラメータをsas
withに渡します./sas $*
。sas
その後、実行して/my_code/my_program.sas
ログを作成します/my_log_folder/my_program.log
。- 次に
run_sas.sh
呼び出しパラメータを分析します。 - そして、ログを次の場所にコピーします。
/admin/.hidden_log_folder/my_program_<today's date>.log
2つのことを変更したい。
マルチワードパラメータの有効化
一部のクライアントは、フォルダとファイル名にスペースを使用して実行する必要があることを絶対に望んでいます/their code/their program.sas
。
./run_sas.sh -sysin "/their code/their program.sas" -log "/their log folder"
/their code/their program.sas
/their log folder
単一の引数を渡す必要があります。sas
特定のパラメータを削除
./sas_utf8
時には代わりに実行する必要があり./sas
、2番目のスクリプトを維持するのはあまりにも怠惰なので、次の追加パラメータを許可したいと思います。
./run_sas.sh -sysin /my_code/my_program.sas -log /my_log_folder -encoding utf8
電話で通話可能
./sas_utf8 -sysin /my_code/my_program.sas -log /my_log_folder
変える
./sas -sysin /my_code/my_program.sas -log /my_log_folder
できれば、これを行うにはどうすればよいですかksh
?
答え1
まず、パラメータをそのまま維持するには、"$@"
not $*
(または)を使用してください。を$@
使用するのと同じように、各パラメータを別々の単語に展開します。"$1" "$2"...
を使用すると、$*
glob文字も問題になります。
utf8オプションを見つけるには、コマンドライン引数を繰り返し、保持したい引数を別の配列にコピーし、と表示されたら-encoding
フラグを設定できますutf8
。
その後、フラグ変数を調べて実行するプログラムを決定し、それをコマンド"${sasArgs[@]}"
に渡します。
だから:
executable="./sas" # The default, for latin encoding
# Inspect the arguments,
# Remember where the log is written
# Change the executable if the encoding is specified
# Copy all arguments except the encoding to the 'sasArgs' array
while [[ "$#" -gt 0 ]]; do
case "$1" in
-encoding)
# change the executable, but do not append to sasArgs
if [[ "$2" = "utf8" ]]; then
executable="./sas_u8"
shift 2
continue
else
echo "The only alternative encoding already supported is utf8" >&2
exit 1
fi
;;
-log)
# remember the next argument to copy the log from
logPath="$2"
;;
esac
sasArgs+=("$1")
shift
done
# To debug: print the args, enclosed in "<>" to discover multi word arguments
printf "Command and args: "
printf "<%s> " "$cmd" "${sasArgs[@]}"
printf "\n"
# exit # when debugging
# Actually run it
"$executable" "${sasArgs[@]}"
# Copy the log using $logPath
# ...
最後のprintf
呼び出しは各引数を囲んで実行する引数を印刷するため、空白の<>
引数が変更されていないことを確認できます。 (実行できますが、2つの引数と1つの引数をecho "${sasArgs[@]}"
区別しません。)foo
bar
foo bar
2つのパラメータペアではなく単一のパラメータを見つけると、最初の部分はループを使用してより簡単になりますfor
。
for arg in "$@" do
case "$arg" in
-encoding-utf8)
# change the executable, but do not append to the array
executable="./sas_u8"
continue
;;
esac
sasArgs+=("$arg")
done
通常のPOSIX shに変換することもできます。ループfor
は与えられたリストのコピーを作成するので、コピーされた引数は配列を使用するset -- "$@" "$arg"
代わりに位置引数(追加)として保存することができます。
さらに、最初にエンコードパラメータを知っている場合は、トランザクション全体がはるかに単純になります。その後、(および)を確認してを使用して削除するだけで$1
十分です。$2
shift
(私はDebianでBashとksh93の両方のバージョンを使って上記のスクリプトをテストしました。私はkshに慣れていないので何かを逃したかもしれません。