Converte lista delimitada por nova linha com espaços em argumentos [duplicado]

3

Estou tentando escrever um script que possa ser executado no menu de contexto do Caja (um clone do Nautilus). Sua finalidade é passar os arquivos selecionados no gerenciador de arquivos para um determinado programa (por exemplo, 7zip). Uma lista de arquivos selecionados é fornecida na variável do sistema $CAJA_SCRIPT_SELECTED_FILE_PATHS , separada por novas linhas. Eu quero passar cada linha desta variável para o programa como um argumento, mesmo que contenham espaços.

Depois de falhar na quebra de cotação, tentei a seguinte linha:

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

Enquanto funcionava para 7zip, eu mudei o script para que os argumentos fossem passados para um programa que eu escrevi e algo deu errado, então eu quero uma maneira de executar isso em um terminal para obter a saída do programa. Eu estava usando xterm -hold -e , mas eu não consegui fazer um comando com um pipe nele executado dessa forma porque o shell tentará canalizar a saída do xterm. Eu também tentei redirecionamento de shell (adicionando > log.txt ao final da linha), e ele fez um arquivo para a saída usual do 7zip, mas um arquivo em branco para o meu programa, que envia mensagens muito bem no terminal.

Finalmente, quero uma solução compatível com POSIX (ou padrão) para que funcione da mesma maneira no BSD e no Linux.

EDIT: Para esclarecer, eu quero mudar alguma coisa como esta:

/path/with/a space
/another/path

No que eu hipoteticamente obteria de algo assim:

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

EDIT2: É assim que deve ser no programa receber os argumentos, não o shell!

    
por Wutaz 24.09.2013 / 15:59

3 respostas

0

Ao tentar fazer algo útil com a resposta de Glenn Jackman, descobri o que é o $ IFS. Parece que era tudo que eu precisava.

Agora tenho este script:

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

Confirmei que funcionava substituindo ./program_to_test por um script BASH que eu escrevi que imprime seus argumentos com realce individual. Quando executei o script acima em Caja, uma janela xterm apareceu e os caminhos para os arquivos selecionados foram todos impressos em destaque, com lacunas no destaque entre os caminhos, mas não entre as palavras nos nomes dos arquivos. Ergo, isso faz com que cada linha seja um argumento.

Eu estou realmente surpreso que havia um método que não requeria ferramentas fora de uma shell parecida com Bourne. Talvez eu não tenha dado crédito a essa ferramenta.

    
por 25.09.2013 / 17:54
3

Se você estiver aberto ao uso do bash, poderá definir IFS para nova linha e read de uma string here para dividir CAJA_SCRIPT_SELECTED_FILE_PATHS em uma matriz. Você pode acessar os elementos da matriz individualmente ou em um loop (usando "${a[@]}" ). Espaços incorporados serão preservados.

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
    
por 24.09.2013 / 16:37
1

Aqui está uma maneira de ler stdin e dividir em novas linhas, mantendo os espaços em branco intactos:

Eu testei com o traço

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