쉘 실행을 함수로 캡슐화하는 방법

쉘 실행을 함수로 캡슐화하는 방법

나는 많은 명령을 실행해야 하는 스크립트를 갖고 있으며 이를 수행할 수 있기를 원합니다.실행을 함수로 캡슐화.

예제 함수는 다음과 같습니다

#!/bin/bash

cmd="redis-cli info | grep cluster_enabled"
cmd1="cmd1"
cmd2="cmd2"

exec(){
    local cmd=$1
    EXEC_RET=$($cmd 2>&1)
    EXEC_STATUS=$?
    echo "$EXEC_RET"
    echo "$EXEC_STATUS"
}

main(){
    exec "$cmd"
}

main "$@"

그러나 실행 후 다음과 같은 오류가 보고됩니다.

$ bash test.sh
ERR syntax error
0

하지만 실행 명령을 추출하지 않으면 오류가 보고되지 않습니다.

exec(){
    EXEC_RET=$(redis-cli info | grep cluster_enabled 2>&1)
    EXEC_STATUS=$?
    echo "$EXEC_RET"
    echo "$EXEC_STATUS"
}
main(){
    exec 
}

main "$@"

# stdout
$ bash temp.sh 
cluster_enabled:1
0

이 오류의 원인과 해결 방법은 무엇입니까? 이에 대한 도움을 주시면 정말 감사하겠습니다.

답변1

redis-cli info | grep cluster_enabled/path/to/redis-cliand 명령 을 실행하기 위한 쉘 구문입니다 /path/to/grep. 첫 번째는 redis-cliinfo두 개의 개별 매개변수로, 두 번째는 grepcluster_enabled두 개의 개별 매개변수로, 파이프를 사용하여 첫 번째 Enter의 표준 출력과 두 번째 Enter의 표준을 연결합니다.

$cmd, in을 사용하여 변수를 $(cmd 2>&1)확장할 때 변수를 IFS로 분할할지 여부 $cmd(공백과 탭 외에 명령줄을 구문 분석할 때 쉘이 수행하는 작업과 아무 관련이 없으며 기본값 $IFS도 의 토큰 쉘 구문 구분 기호임) , 파일 이름 생성(소위 분할+glob) 및 첫 번째 결과 단어에서 파생된 명령을 실행하여 모든 단어를 인수로 사용합니다. 따라서 의 코드를 평가하지도 않고 $cmd에 저장된 이름이 필요한 명령을 실행하지도 않습니다.$cmd"$cmd"

따라서 명령을 실행하는 대신 함수에 전달된 인수가 셸 구문의 코드로 평가되기를 원하는 것 같습니다.

게다가 exec이는 이미 쉘의 특수 내장 함수이며 여러 쉘(bash 포함)의 경우 shPOSIX 모드에서 또는 더 일반적으로 호출될 때 함수로 재정의될 수 없습니다.

그래서

run(){
    local shell_code="$1"
    RUN_STDOUT_AND_ERR=$(eval " $shell_code" 2>&1)
    RUN_STATUS="$?"
    printf '%s\n' "$RUN_STDOUT_AND_ERR" "$RUN_STATUS"
    return "$RUN_STATUS"
}

run "$cmd"

관련 정보