Bash 스크립트에서 복잡한 명령 실행

Bash 스크립트에서 복잡한 명령 실행

Bash 스크립트에서 다음 명령을 실행하려고 합니다.

rm -rf `ls -t ${FOLDER}/other_folder | awk 'NR>5'`

비슷한 것을 시도하고 있습니다.

RM_CMD="$(rm -rf 'ls -t ${FOLDER}/other_folder | awk NR>5')"

나중에 함수에서 사용하여 명령이 실제로 실행되기를 원합니다.

여러 변형을 시도했지만 항상 실패했습니다. 여기서 올바른 접근 방식은 무엇입니까?

-편집하다-

추가 정보

내가 다음과 같은 것을 시도하면

RM_CMD="rm -rf `ls -t ${FOLDER}/other_folder | awk 'NR>5'`"

명령을 즉시 실행하려고 시도하는 것 같습니다. 이는 내 의도가 아니지만(나중에 실행하기 위해 올바른 명령을 저장하고 싶습니다) 올바른 값을 모두 얻습니다. 즉, 빈 값은 하나도 없습니다.

-편집 2-

나는 다음과 같이 명령을 최대한 많이 나누려고 노력합니다.

LS_CMD="ls -t ${FOLDER}/other_folder"    
AWK_CMD="awk 'NR>5' ${LS_CMD}"    
RM_CMD="rm -rf '${AWK_CMD}'"

하지만 이런 문제가 발생합니다.

+ ssh -t user@server 'rm -rf '\''awk '\''NR>5'\'' ls -t /full/path/to/folder/other_folder'\'''
bash: 5 ls -t /full/path/to/folder/other_folder: No such file or directory

답변1

일반적으로 이와 같은 질문에 대한 대답은 다음을 읽는 것입니다.BashFAQ #50: "명령을 변수에 넣으려고 하는데 복잡한 경우에는 항상 실패합니다!". 간략한 요약: 변수는 실행 가능한 코드가 아닌 데이터를 위한 것이므로 코드를 삽입하려고 하면 온갖 종류의 문제에 직면하게 됩니다.

하지만 이 경우에는 또 다른 핵심 요소가 있습니다. 를 통해 명령을 실행한다는 것입니다 ssh. 즉, 명령이 원격 시스템으로 전달된다는 의미입니다.데이터로, 원격 시스템의 셸에 의해 명령으로 구문 분석됩니다. 이는 스크립트(로컬 시스템)의 변수에 명령(데이터)을 저장하는 것이 의미가 있음을 의미합니다.

당신이 가진 가장 큰 문제는 백틱을 사용하거나 $( )작은 따옴표로 묶이지 않은 경우 내부 명령이 즉시 (로컬 시스템에서) 실행되고 해당 출력이 변수에 저장된다는 것입니다. 이를 방지하려면 변수를 정의할 때 관련 문자를 이스케이프 처리하면 됩니다.

RM_CMD="rm -rf \$(ls -t '${FOLDER}/other_folder' | awk 'NR>5')"

$( )일반적으로 선호되기 때문에 백틱을 대신 사용하고 있습니다 . 제가 보기에는 역따옴표와 작은따옴표를 어느 시점에서 혼동한 것 같습니다. 둘은 비슷해 보이지만 완전히 다른 효과를 가지고 있습니다. $( )본질적으로 동일한 작업을 수행하지만 시각적으로 모호하지는 않습니다.

${FOLDER}또한 로컬 컴퓨터의 변수이므로 즉시 확장해야 한다고 가정합니다 (공백이나 다른 쉘 메타 문자가 포함된 경우에는 주위에 작은따옴표를 추가했습니다). 원격 쉘, 용도 변경 \"\${FOLDER|/other_folder\". 실제로 ${FOLDER}작은따옴표 자체가 포함된 경우 작은따옴표를 둘러싸는 것은 작동하지 않습니다. 이 문제를 해결할 수 있는 방법이 있지만 여기서는 고민하지 않습니다.

변수 할당에 작은 따옴표를 사용할 수도 있지만 명령에서 작은 따옴표를 사용하는 데 문제가 발생할 수 있으며 (작은 따옴표로 묶인 문자열 내에 작은 따옴표를 중첩할 수 있는 확실한 방법은 없습니다) 로컬에서 awk이를 수행할 수 있는 깔끔한 방법이 없습니다. ${FOLDER}기계를 확장하세요. 이는 참조를 혼합하여 해결할 수 있지만 지저분합니다.

마지막으로 변수를 사용할 때는 큰따옴표로 묶어야 합니다.

ssh -t user@server "$RM_CMD"

...이 특별한 경우에는 문제가 되지 않지만 큰따옴표가 아닌 변수 참조에는 모든 종류의 문제가 있을 수 있으므로 일반적으로 큰따옴표를 사용하는 것이 좋습니다.

답변2

다음 명령을 사용하여 bash 스크립트의 일반적인 오류를 확인할 수 있습니다.주택 검사, 온라인으로 작동할 뿐만 아니라오프라인 프로그램. 다양한 쉘(shebang으로 식별됨)을 지원하고 스타일 경고도 제공합니다(귀하의 경우 $(...)백틱 대신 사용). 붙여넣은 코드를 실시간으로 편집하고 등급을 확인할 수도 있습니다(코딩 스타일에 대한 일반 튜토리얼과 함께 사용하면 도움이 됩니다).

관련 정보