aspas geradas por outro script Bash não são tratadas como citações dentro do script original [duplicado]

2

Usando o bash, meu pwd contém diretórios com espaços:

$ pwd
/a/b c/d

Isso funciona:

$ ls "$PWD"
bar foo
# yay!

Também funciona se eu colocar esse código dentro de um script. Agora, se eu dividir esse comando em dois:

$ cat foo 
echo \"$PWD\"
$ cat bar 
ls $(./foo)

foo gera o caminho entre aspas:

$ ./foo 
"a/b c/d"
# ok

mas bar não está tratando as cotações da maneira que eu esperava:

$ ./bar 
ls: "/a/b: No such file or directory
ls: c/d": No such file or directory
# boo!

Isso não é acadêmico. O comando que eu realmente quero dividir é horrível. Em vez de tê-lo em um único script, quero dividi-lo em dois scripts: um que gere os parâmetros citados corretamente e outro que seja simplificado drasticamente (e chame esse primeiro). Acontece que essa horrenda lista de parâmetros é útil para vários comandos, então essa é outra razão para tê-la em um script separado.

atualização 1 : isso funciona BTW:

$ cat foo
ARGS="$PWD"
$ cat bar
source ./foo
ls "$ARGS"
$ ./bar
bar foo

Mas parece ser arriscado colocar os argumentos em uma variável.

update 2 : a solução @ user454038 funciona para um único espaço em um nome de diretório, mas quebra em dois espaços.

atualização 3 : @mikeserv e @ user454038 me ensinaram o suficiente para que eu funcionasse (para um e dois, e provavelmente mais, espaços em nomes de diretório):

$ cat foo 
echo "$PWD"
$ cat bar
ls "$(./foo)"

Lá vamos nós! Obrigado a todos!

    
por Bill Burcham 18.12.2015 / 03:40

1 resposta

3

A questão é como @mikeserv apontou, as citações. Excesso de cotações. A solução é não ter aspas no seu foo em primeiro lugar:

estrutura dir (e temos cd para o d dir):

~
└── a
    └── b c
        └── d

Dentro de d dir, já temos foo e bar você postou. Mas agora crie:

foo2 :

echo $PWD

bar2 :

set -x
ls "$(./foo2)"
  • temos set -x para que você possa ver claramente o que está acontecendo

Quando você executa o /bar no prompt de comando, você vê:

$ ./bar2
+++ ./foo2
++ ls '/home/youruser/a/b c/d'
bar  bar2  foo  foo2

Basta remover o set -x do código para obter a saída desejada com êxito:

bar  bar2  foo  foo2

Explicação

Se você adicionar set -x ao seu bar original e executar, verá

$ ./bar
+++ ./foo
++ ls '"/home/youruser/a/b c/d"'
ls: cannot access "/home/youruser/a/b c/d": No such file or directory

Isso é o mesmo que no prompt de comando que você executou:

$ ls '"/home/youruser/a/b c/d"'
ls: cannot access "/home/youruser/a/b c/d": No such file or directory
  • O culpado é o extra " quote
  • , que foi introduzido no seu original foo
  • assim que " for removido, ls funcionará

Assim, remover as citações no seu foo original, como fizemos com foo2 , garante que ls o receba corretamente sem aspas excessivas e, em seguida, funciona.

    
por 18.12.2015 / 04:42

Tags