쉘 스크립트에서 기능하도록 내보내기 명령 전달

쉘 스크립트에서 기능하도록 내보내기 명령 전달
#!/bin/sh

execute_cmd()
{
   $($@)
}

execute_cmd export MY_VAR=my_val
echo ${MY_VAR}

$()서브쉘에서 실행되기 때문에 $MY_VAR스크립트가 실행되는 쉘에서는 올바르게 설정되지 않습니다.

제 질문은 내보내기 명령을 함수에 전달하고 스크립트가 실행 중인 현재 셸에서 어떻게 실행합니까?입니다.

답변1

무엇을 하려는지 명확하지 않습니다. $($@)말도 안 되는 소리지만, 당신은 무엇을 하고 싶나요?

무엇 $($@)인가요:

  • 함수의 매개변수를 가져옵니다. 이것은 문자열 목록입니다.
  • 공백이 포함된 각 섹션을 추가로 분할합니다.
  • 각 분할을 가져와 와일드카드 패턴으로 해석합니다. 패턴이 파일과 일치하는 경우 이 부분은 일치하는 파일 이름 목록으로 대체됩니다.
  • 첫 번째 부분을 실행할 명령 이름(함수, 셸 내장 또는 실행 파일)으로 사용하고 다른 부분을 인수로 전달합니다.
  • 명령의 출력을 가져와서 공백이 포함된 곳마다 분할합니다.
  • 각 분할을 가져와 와일드카드 패턴으로 해석합니다. 패턴이 파일과 일치하는 경우 이 부분은 일치하는 파일 이름 목록으로 대체됩니다.
  • 첫 번째 부분을 실행할 명령 이름(함수, 셸 내장 또는 실행 파일)으로 사용하고 다른 부분을 인수로 전달합니다.

이것이 복잡하게 들린다면, 그렇기 때문입니다.

execute_cmd export MY_VAR=my_val당신이 그것을 구현 하고 싶다면 export MY_VAR=my_val, 왜 귀찮게 하겠습니까 execute_cmd?

이를 합리적으로 설명하는 방법에는 두 가지가 있습니다.

  1. 매개변수와 함께 명령을 함수에 전달하려고 합니다. 인수가 있는 명령은 문자열 목록이며 첫 번째는 함수 이름, 쉘 내장 또는 실행 파일입니다. 그러면 제공된 매개변수를 사용하여 이 명령을 호출하는 구문은 입니다 "$@".

    execute_cmd () {
      "$@"
    }
    execute_cmd export MY_VAR=my_val
    

    큰따옴표는 위에서 언급한 분할 및 와일드카드 확장 단계를 방지합니다.변수 대체에는 항상 큰따옴표를 사용하십시오..

    export또한 키워드/내장 기능의 이중 특성에 유의하세요. 키워드의 존재로 인해 쉘은 export MY_VAR=$(seq 10)구문 분석에서와 같이 출력을 할당할 수 있지만 명령이 여기에 없기 때문에 쉘은 이를 할당으로 구문 분석하지 않습니다. 따라서 일반 명령에 대한 인수로 구문 분석되고 분할됩니다. +glob은 에서 수행되므로 다음이 필요합니다.seq 10$MY_VARMY_VAR=$(seq 10)exportMY_VAR=$(seq 10)execute_cmd export MY_VAR=$(seq 10)exportexecute_cmdMY_VAR=$(seq 10)$(seq 10)execute_cmd export MY_VAR="$(seq 10)"

  2. 쉘 조각을 실행하고 싶습니다. 쉘 조각은 단일 인수로 전달되는 단일 문자열입니다. 쉘 코드가 포함된 문자열을 실행하려면 eval내장 함수를 사용하십시오.

    execute_cmd () {
      eval "$1"
    }
    execute_cmd 'export MY_VAR=my_val'
    

기본적으로는 1 로 가정됩니다 IFS. 이것을 알고 있다면 이 단락을 읽을 필요가 없습니다.

답변2

당신은 그것을 확인해야합니다자일스의 대답모든 세부정보를 확인하세요. eval즉, 다음을 사용할 수 있습니다 $().

execute_cmd()
{
    eval "$@"
}

~에서배쉬 매뉴얼:

평가[매개변수]

이러한 인수는 함께 연결되어 명령을 형성한 다음 읽고 실행되며 종료 상태는 eval의 종료 상태로 반환됩니다. 매개변수가 없거나 빈 매개변수만 있는 경우 반환 상태는 0입니다.

다른 껍질에는 일반적으로eval 내장유사한 의미를 갖습니다.

관련 정보