공백이 있는 개행으로 구분된 목록을 매개변수로 변환

공백이 있는 개행으로 구분된 목록을 매개변수로 변환

Caja(노틸러스 복제품)의 컨텍스트 메뉴에서 실행할 수 있는 스크립트를 작성하려고 합니다. 그 목적은 파일 관리자에서 선택한 파일을 특정 프로그램(예: 7zip)에 전달하는 것입니다. 선택한 파일의 $CAJA_SCRIPT_SELECTED_FILE_PATHS줄바꿈으로 구분된 목록이 시스템 변수에 제공됩니다 . 이 변수의 모든 줄에 공백이 포함되어 있더라도 매개변수로 프로그램에 전달하고 싶습니다.

견적 포장이 실패한 후 다음 줄을 시도했습니다.

echo "$CAJA_SCRIPT_SELECTED_FILE_PATHS" | xargs -d "\n" 7z a archive.7z

7zip에서는 작동하지만 내가 작성한 프로그램에 인수를 전달하도록 스크립트를 변경했지만 문제가 발생하여 터미널에서 이 스크립트를 실행하여 프로그램의 출력을 얻을 수 있는 방법을 원합니다. 을 사용하고 있지만 xterm -hold -e쉘이 xterm의 출력을 파이프하려고 시도하기 때문에 파이프가 있는 명령을 이런 방식으로 실행할 수 없습니다. 나는 또한 ( > log.txt줄 끝에 추가하여) 쉘 리디렉션을 시도했고 7zip의 일반적인 출력을 위한 파일을 생성했지만 터미널에 메시지를 정상적으로 출력하는 내 프로그램에 대한 빈 파일을 생성했습니다.

마지막으로, BSD와 Linux에서 동일한 방식으로 작동할 수 있도록 POSIX(또는 기타 표준) 호환 솔루션을 원합니다.

편집: 명확히 하기 위해 다음과 같이 변경하고 싶습니다.

/path/with/a space
/another/path

다음과 같은 것에서 무엇을 얻을 수 있는지 말해 봅시다.

char *argv[]={"/path/with/a space", "/another/path"};

EDIT2: 이것은 쉘이 아니라 매개변수를 수신하는 프로그램의 모습입니다!

답변1

Bash를 사용하려는 경우 여기에서 IFS개행을 설정하고 read문자열을 배열로 분할 할 수 있습니다 CAJA_SCRIPT_SELECTED_FILE_PATHS. "${a[@]}"그런 다음 개별적으로 또는 루프에서 배열 요소에 액세스할 수 있습니다( 내장된 공간은 보존됩니다.

CAJA_SCRIPT_SELECTED_FILE_PATHS='a
b c
d
f
g'
IFS=$'\n' read -d '' -r -a a <<< "$CAJA_SCRIPT_SELECTED_FILE_PATHS"
printf "%s\n" "${a[0]}"
a
printf "%s\n" "${a[1]}"
b c
printf "%s\n" "${a[@]}"
a
b c
d
f
g

답변2

공백을 그대로 유지하면서 stdin을 읽고 개행 문자로 분할하는 방법은 다음과 같습니다.

대시로 테스트했어요

#!/bin/dash
while IFS= read -r line; do
    set -- "$@" "$line"
done
printf "have arg '%s'\n" "$@"

답변3

Glenn Jackman의 답변에서 유용한 것을 얻으려고 할 때 $IFS가 무엇인지 알아냈습니다. 이것이 나에게 필요한 것 같습니다.

지금은 다음 스크립트가 있습니다.

#!/bin/sh
IFS='
'
uxterm -hold -e ./program_to_test $CAJA_SCRIPT_SELECTED_FILE_PATHS

./program_to_test인수를 개별 강조 표시로 인쇄하는 BASH 스크립트를 대체하여 작동한다는 것을 확인했습니다. Caja에서 위 스크립트를 실행하면 xterm 창이 나타나고 선택한 파일의 경로가 모두 강조 표시됩니다. 강조 표시 사이에는 공백이 있지만 파일 이름의 단어 사이에는 공백이 없습니다. 따라서 각 행이 매개변수가 됩니다.

사실 Bourne과 같은 쉘 외에는 아무것도 필요하지 않은 방법이 있다는 것에 놀랐습니다. 어쩌면 내가 이 도구에 충분한 신용을 부여하지 않았을 수도 있습니다.

관련 정보