인수를 확장하지 않고 Bash 명령이 포함된 문자열을 분할하는 방법은 무엇입니까?

인수를 확장하지 않고 Bash 명령이 포함된 문자열을 분할하는 방법은 무엇입니까?

쉘 명령줄이 포함된 문자열이 있습니다. 이 문자열에서 특정 매개변수가 있는 경우 이를 제거하고 유효한 쉘 명령을 유지하면서 결과를 인쇄해야 합니다. 어떻게 해야 하나요?

나는 두 가지 다른 접근 방식을 시도했습니다.

그러나 두 솔루션 모두 매개변수 대체를 수행합니다. 즉, 명령이 이면 docker run --name $boxid매개변수는 $boxid명령을 패치했을 때의 값으로 대체됩니다. 매개변수를 확장하지 않은 상태로 유지해야 합니다.

보다 완전한 예를 제공하려면 다음 명령 문자열을 고려하십시오.

docker run -v /foo:/foo:ro --name "$boxid" container bash -c "some shell string"

그리고 Bash가 동일한 방식으로 구문 분석할 수 있도록 다른 모든 매개 변수를 유지하면서 다음 세 가지 결과가 모두 허용될 수 있도록 -v /foo…어디든 있을 수 있는 해당 매개 변수를 제거해야 할 것입니다 .docker run

docker run --name "$boxid" container bash -c "some shell string"
docker run --name "$boxid" container bash -c some\ shell\ string
"docker" "run" "--name" "$boxid" "container" "bash" '-c' "some shell string"

이것은 심각하게 잘못된 요청/XY 질문처럼 들리므로 몇 가지 배경 지식을 제공하겠습니다.

launch명령( )을 실행하는 셸 함수( )가 포함된 대규모 소프트웨어(Nextflow)의 일부인 Bash 스크립트가 있습니다 docker run …. 명령에는 특정 경우에 오류가 발생하므로 제거해야 하는 매개변수가 포함될 수 있습니다. 1

나는 스크립트 자체를 제어할 수 없지만 소프트웨어를 사용하면 launch함수가 호출되기 전(그러나 함수가 정의된 후에) 사용자가 임의의 Bash 코드를 스크립트에 삽입할 수 있습니다. 그래서 내 생각은 기본적으로 launch함수를 동적으로 재정의하는 다음 코드 조각을 삽입하는 것입니다 .

eval "$(declare -f launch | sed '/docker run/s/OFFENDING ARGUMENT//')"

이것은 작동합니다. 그러나 불행하게도 이는 미래에도 사용할 수 없습니다. 스크립트를 조금만 변경하면 간단한 텍스트 교체가 중단될 수 있습니다. 패치를 더욱 강력하게 만들어야 합니다. 그리고 Bash만 설치된 상태에서 베어메탈에서 실행될 수도 있기 때문에 다른 프로그래밍 언어로 변환할 수 없습니다.


1 이것은 소프트웨어의 버그가 아닙니다. 제 사용 사례는 소프트웨어 사양을 약간 벗어났습니다.

관련 정보