Expandir variável de ambiente de PIPE (SHELL)

0

Eu tenho uma pergunta que pode ou não ter uma resposta no formulário que estou procurando, mas qualquer formulário será suficiente.

Eu tenho atualmente um arquivo de configuração, no qual usarei um comando shell no grep para encontrar uma linha específica dentro do arquivo, então eu uso sed para obter todo o texto depois de um caractere específico. O texto restante é simplesmente um caminho de arquivo que inclui uma variável de ambiente. A saída do comando retorna algo assim:

$ LIGHTS_HOME / music / something.mp3

Eu então quero canalizar isso para o mp3info para obter metadados utilizáveis do arquivo mp3. No entanto, quando eu canalizo para mp3info $ LIGHTS_HOME não expande para o caminho real do arquivo ao qual está correlacionado. Como posso expandi-lo dentro de uma linha? Isso é possível?

Aqui está o meu comando atual:

$ sudo grep -w "file_path =" /home/pi/lightshowpi/config/state.cfg | 
sed 's/.*= //' | sed  's|'\$LIGHTS_HOME'| '/home/pi/lightshowpi'|' |
xargs mp3info -p "Now Playing: %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py

O que o comando está fazendo (eu editei a linha para que ela seja mais fácil de ler, em uso ela precisará ser uma única linha (de preferência, eu estou aberto para múltiplas linhas se necessário):

a primeira linha usa o grep para encontrar a linha 'file_path =', que retorna a linha 'file_path = $ LIGHTS_HOME / music / songname.mp3'

Que é então canalizado para sed que analisa a instrução e retorna todos os caracteres após o '=', que retorna neste caso '$ LIGHTS_HOME / music / songname.mp3'

A partir daí, eu uso um segundo comando sed para substituir $ LIGHTS_HOME por seu valor variável '/ home / pi / lightshowpi /'

Idealmente, eu gostaria de me livrar dessa segunda instrução sed em favor de algo que avalia '$ LIGHTS_HOME' como seu valor '/ home / pi / lightshowpi /'

Que então será usado pelo mp3info para obter os meta-dados do arquivo, que é formatado como um stdout que é canalizado para o xargs que prepara o meta stdout para um formato stdin que o script python usa e twita o valor com alguns outros caracteres emoticon (que o script python faz sem um problema)

No entanto, em vez de usar um segundo comando sed de substituir $ LIGHTS_HOME por / home / pi / lightshowpi eu preferiria ter $ LIGHTS_HOME expandido, pois em outras instalações essa variável poderia ser definida em algum lugar diferente do diretório base.

Eu acho que devo observar, que estou tentando isso enquanto no terminal, eu não estou colocando isso dentro de um script de shell. Eu não tenho certeza se isso muda as coisas, eu ainda estou fazendo o meu melhor para aprender shell, mas acredito que isso pode mudar as coisas com base nos erros que eu continuo recebendo.

    
por Brett Reinhard 05.12.2016 / 21:17

3 respostas

1

Essencialmente, esta linha de código pesquisa um arquivo de configuração /home/pi/lightshowpi/config/state.cfg para a linha "file_path=" e então expande a variável de ambiente $ SYNCHRONIZED_LIGHTS_HOME para seu valor e canaliza para mp3info que extrai o arquivo metadados do arquivo MP3, em seguida, canaliza a string para um script Python que pega os argumentos e remove caracteres indesejados ao incluir emoticons de uma biblioteca de emoticons em Python para twittar para sua conta através da API de twitters.

sed '/file_path =/!d;s|.*= ||;s|$SYNCHRONIZED_LIGHTS_HOME|'"$SYNCHRONIZED_LIGHTS_HOME|" /home/pi/lightshowpi/config/state.cfg | xargs mp3info -p "Now Playing %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py

A chave para este comando está usando! para excluir o 'file_path =' então usando xargs para mp3info e tweet.py

Vou depurar o seguinte /home/pi/lightshowpi/config/state.cfg usando a mesma variável $ SYNCHRONIZED_LIGHTS_HOME em vez de / home / pi / lightshowpi para tornar este comando universal para este projeto de código aberto.

    
por 06.12.2016 / 02:40
2

Com o ZSH, você pode "executar expansão de parâmetros, substituição de comando e expansão aritmética" com o sinalizador de expansão do parâmetro (e) em algo em uma determinada variável x (consulte zshexpn(1) para obter detalhes):

x='$HOME/blablah'; echo $x; echo ${(e)x}

Ou de um arquivo:

echo '$HOME/fromfile' > afile
echo ${(e)$(<afile)}

Isso tem várias vantagens sobre eval , dependendo de quem tem acesso ao arquivo de configuração e de como elas são impertinentes:

$ touch somefile
$ echo 'hi; rm somefile' > x
$ eval "echo 'cat x'"       
hi
$ ls somefile
ls: somefile: No such file or directory
$ exec zsh
% touch somefile
% echo ${(e)$(<x)}
hi; rm somefile
% ls somefile
somefile
% 
    
por 05.12.2016 / 21:48
0

Supondo que você tenha o valor $ LIGHTS_HOME / music / something.mp3 em uma variável $ myvar

você pode expandi-lo via:

mp3info $(eval echo $myvar)
    
por 05.12.2016 / 21:37