Avaliação da string Bash pouco clara

Avaliação da string Bash pouco clara

Considere o seguinte em um script bash:

STOP_SEARCH_STR="'""for $TASKNAME""'"
echo $STOP_SEARCH_STR               # prints 'for Our Special Task_4'
echo "$STOP_SEARCH_STR"             # prints 'for Our Special Task_4'
echo "grep -F "$STOP_SEARCH_STR" "$TEMP"/draft" # prints grep -F 'for Our Special Task_4' /tmp/draft
echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft)"  # prints nothing!
echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")  # prints nothing!

E o seguinte conteúdo no arquivo de texto $TEMP/draft:

2019-11-21 08:13:58,825 Task started: 'Our Special Task_4' of type 'Our - Special Task' 
2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

Se eumanualmentedigite o comando grep -F 'for Our Special Task_4' /tmp/draft, recebo a segunda linha no arquivo de texto de rascunho:

2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

Mas os dois últimos comandos acima (dentro de um script bash) não imprimem nada!

Alguma ideia do porquê?

Responder1

As cotações não são especiais depois que uma variável é expandida.

Supondo que TASKNAMEcontém Our Special Task_4, então STOP_SEARCH_STRestá definido como 'for Our Special Task_4', incluindo essas aspas. Isso é o que você echomostra.

Quando você executa grep -F "$STOP_SEARCH_STR" "$TEMP"/draft, você está dando grepa string 'for Our Special Task_4'para procurar. Essa string não existe no arquivo, portanto nenhuma linha corresponde e grepnão imprime nada.

Remova as aspas, você não está procurando por elas:

task="Our Special Task_4"
str="for $task"
grep -F "$str" "$TEMP/draft"

Nota: vocêfazerprecisar de aspas duplas ao redor da expansão da variável "$str"ou "$STOP_SEARCH_STR"para evitar a divisão de palavras, consultePor que meu script de shell engasga com espaços em branco ou outros caracteres especiais?

Quando vocêmanualmentedigite o comando grep -F 'for Our Special Task_4' /tmp/draft, as aspas fazem parte da sintaxe do shell e removem efetivamente o significado especial dos espaços dentro delas. Isso é diferente das aspas dentro de uma variável que agem como caracteres comuns.


Como um aparte: 1) echo "$(somecmd)"geralmente é redundante, você pode simplesmente executar somecmddiretamente. 2) Aqui: echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft"), por causa de como as aspas circundam o espaço em branco, você está tentando executar um comando chamado grep -F 'for. Você provavelmente deve receber um erro por isso:

$ echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")
bash: grep -F 'for: command not found

Responder2

Você deve alterar esta linha:

STOP_SEARCH_STR="'""for $TASKNAME""'"

para esta linha (sim, não são necessárias aspas simples, elas não são úteis):

STOP_SEARCH_STR="for $TASKNAME"

E use esta linha no script (sim, citada conforme mostrado):

grep -F "$STOP_SEARCH_STR" "$TEMP"/draft

Se você quiser/precisar adicionar um echo (que é supérfluo e pode até causar problemas) use esta linha (sim, cite todas as expansões (variáveis ​​e subshell)):

echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")"

informação relacionada