매개변수와 함께 명령을 스크립트에 전달

매개변수와 함께 명령을 스크립트에 전달

나는 글을 쓰려고 노력 중이야쉘 스크립트입력으로 수신매개변수가 있는 명령그리고 실행하세요.

cron예를 들어 다음과 같이 사용하고 싶습니다 .

0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."

세부 사항은 my_wrapper.sh중요하지 않지만 스크립트 zsh이고 그것을 받아 호출하고 싶습니다 command arg1 arg2 arg3 .... 매개변수에는 작은따옴표, 큰따옴표 등이 포함될 수 있습니다.

매개변수가 포함된 명령을 스크립트에 전달하고 수신하는 올바른 방법은 무엇입니까?

고쳐 쓰다:

zsh를 사용한 명령줄에서 @Gilles의 첫 번째 솔루션은 훌륭하게 작동합니다.

#!/bin/zsh
task_name=$1
shift
"$@" > /path/to/logging_directory/$task_name

그런 다음 > my_wrapper.sh date "%Y-%b-%d" 명령줄에서 호출하면 작업이 수행됩니다.

그러나 다음과 같이 사용하려고 하면 다음과 같습니다 cron.

CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"

이것은 작동하지 않습니다.

최종 업데이트(문제 해결):

Giles의 대답은 다음과 같습니다.crontab필요도망가다어떤 %표시라도. 위의 내용을 다음으로 변경합니다.

CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+\%Y-\%b-\%d"

효율적인. 알았어, 알았어.

답변1

두 가지 옵션이 있습니다. 실행할 일부 매개변수가 포함된 프로그램을 전달하거나 쉘 스크립트를 전달할 수 있습니다. 두 개념 모두 "명령"이라고 부를 수 있습니다.

일부 매개변수를 사용하는 프로그램문자열 목록 형식을 취합니다. 여기서 첫 번째는 실행 파일의 경로(또는 환경 변수가 나타내는 디렉터리 목록에서 찾을 수 있는 슬래시가 없는 이름 PATH)입니다. 이것의 장점은 사용자가 인용에 대해 걱정하지 않고 명령에 인수를 전달할 수 있다는 것입니다. sh -c …원하는 경우 쉘을 명시적으로 호출할 수 있습니다. 이 옵션을 선택하는 경우 각 문자열(프로그램 및 해당 인수)을 별도의 인수로 스크립트에 전달합니다. 이는 일반적으로 스크립트의 마지막 매개변수입니다(더 많은 매개변수를 전달하려면 특수 문자열을 프로그램 종료 매개변수 표시로 지정해야 하며, 다음을 수행하지 않는 한 이를 프로그램에 전달할 수 없습니다). 구문이 더 복잡함)

0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...

스크립트에서:

#!/bin/zsh
task_name=$1
shift
"$@"

쉘 스크립트sh실행을 위해 프로그램에 전달되는 문자열입니다. 이를 통해 사용자는 쉘을 명시적으로 호출하지 않고도 쉘 조각을 작성할 수 있으며 단일 문자열이므로 프로그램에 대한 단일 인수이므로 구문 분석하기가 더 쉽습니다. sh스크립트 에서는 를 호출할 수 있지만 evalzsh에서는 수행하지 마십시오. 사용자는 sh 구문과 약간 다른 zsh 구문을 작성할 필요가 없기 때문입니다.

0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."

스크립트에서:

#!/bin/zsh
task_name=$1
sh -c "$2"

답변2

이를 처리하는 가장 좋은 방법은 실제 명령 인수를 문자열 대신 인수로 래퍼에 전달하는 것입니다. 래퍼를 다음과 같이 호출할 수 있습니다.

my_wrapper "task_name" command arg1 arg2 arg3

my_wrapper다음이 포함됩니다:

task_name=$1
shift # remove the task_name from the command+args
"$@" # execute the command with args, while preserving spaces etc

답변3

대시 옵션에도 비슷한 문제가 있다고 생각합니다. 검색에서 이 문제를 발견했기 때문에 도움이 된 내용을 공유해야겠다고 생각했습니다. 나는 다음 crontab을 사용하고 있습니다 :

0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt

Bash 스크립트에서는 이것을 사용하여 -f 옵션을 얻습니다.

while getopts ":f" opt; do
    case $opt in
        f)
            force_full=1
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            ;;
    esac
done

그래서 어떤 이유로 cron을 통해 이것을 실행했을 때 옵션이 실행되지 않는다는 것을 알았습니다. 음, cronjob에 /bin/bash를 추가하면 이 문제가 해결됩니다. 새로운 크론탭은 다음과 같습니다:

0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt

관련 정보