La evaluación de la cadena Bash no está clara

La evaluación de la cadena Bash no está clara

Considere lo siguiente en un 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!

Y el siguiente contenido en el archivo 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

Si yoa manoescriba el comando grep -F 'for Our Special Task_4' /tmp/draft, recibo la segunda línea en el borrador del archivo de texto:

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

¡Pero los últimos 2 comandos anteriores (dentro de un script bash) no imprimen nada!

¿Alguna idea de por qué?

Respuesta1

Las comillas no son especiales después de expandir una variable.

Suponiendo que TASKNAMEcontiene Our Special Task_4, entonces STOP_SEARCH_STRse establece en 'for Our Special Task_4', incluidas esas comillas. Eso es lo que tus echoprogramas.

Cuando corres grep -F "$STOP_SEARCH_STR" "$TEMP"/draft, estás dando grepla cadena 'for Our Special Task_4'a buscar. Esa cadena no existe en el archivo, por lo que ninguna línea coincide y grepno imprime nada.

Elimina las comillas, no las estás buscando:

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

Nota: ustedhacernecesita las comillas dobles alrededor de la expansión variable "$str"o "$STOP_SEARCH_STR"para evitar la división de palabras, consulte¿Por qué mi script de shell se atasca con espacios en blanco u otros caracteres especiales?

Cuando usteda manoescriba el comando grep -F 'for Our Special Task_4' /tmp/draft, las comillas son parte de la sintaxis del shell y eliminan efectivamente el significado especial de los espacios dentro de ellas. Esto es diferente de las comillas dentro de una variable que actúan como caracteres comunes.


Como comentario aparte: 1) echo "$(somecmd)"suele ser redundante, puedes ejecutarlo somecmddirectamente. 2) Aquí: echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft"), debido a cómo las comillas rodean el espacio en blanco, estás intentando ejecutar un comando llamado grep -F 'for. Probablemente deberías recibir un error por eso:

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

Respuesta2

Deberías cambiar esta línea:

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

a esta línea (sí, no se necesitan comillas simples, no son útiles):

STOP_SEARCH_STR="for $TASKNAME"

Y use esta línea en el guión (sí, citada como se muestra):

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

Si desea/necesita agregar un eco (que es superfluo e incluso puede causar problemas), use esta línea (sí, cite todas las expansiones (variables y subcapa)):

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

información relacionada