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
두 가지 사항을 변경하고 싶습니다.
다중 단어 매개변수 활성화
일부 클라이언트는 폴더 및 파일 이름에 공백을 사용하고 실행하도록 요구하기를 절대적으로 원합니다 /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
하고 두 번째 스크립트를 유지하기에는 너무 게으른 편이므로 다음과 같은 추가 매개변수를 허용하고 싶습니다.
./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
호출은 각 인수를 둘러싸서 실행할 인수를 인쇄하므로 <>
공백이 있는 인수가 변경되지 않은 상태로 유지되는지 확인할 수 있습니다. (실행할 수는 있지만 두 인수 와 단일 인수를 echo "${sasArgs[@]}"
구별하지 않습니다 .)foo
bar
foo bar
두 매개변수 쌍이 아닌 단일 매개변수를 찾는 경우 첫 번째 부분은 루프를 사용하여 더 간단하게 만들 수 있습니다 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에 익숙하지 않아서 뭔가 놓쳤을 수도 있습니다. 하지만 Bash의 배열은 ksh에서 복사되었으므로 똑같이 잘 작동할 것으로 기대합니다. 시간. )