Quiero imprimir un código en un archivo usando cat <<EOF >>
:
cat <<EOF >> brightup.sh
!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
pero cuando compruebo la salida del archivo, obtengo esto
!/bin/bash
curr=1634
if [ -lt 4477 ]; then
curr=406;
echo > /sys/class/backlight/intel_backlight/brightness;
fi
He probado a poner comillas simples pero la salida también lleva las comillas simples. ¿Cómo puedo evitar este problema?
Sólo es necesario un cambio mínimo; poner en comillas simples el delimitador de aquí-documento después de <<
.
cat <<'EOF' >> brightup.sh
o, de forma equivalente, la barra diagonal inversa:
cat <<\EOF >>brightup.sh
Sin las comillas, el documento de aquí sufrirá la sustitución de variables, se evaluarán las barras invertidas, etc., como has descubierto.
Si necesitas expandir algunos valores, pero no todos, debes escapar individualmente los que quieras evitar.
cat <<EOF >>brightup.sh
#!/bin/sh
# Created on $(date # : <<-- this will be evaluated before cat;)
echo "\$HOME will not be evaluated because it is backslash-escaped"
EOF
producirá
#!/bin/sh
# Created on Fri Feb 16 11:00:18 UTC 2018
echo "$HOME will not be evaluated because it is backslash-escaped"
Como sugiere @fedorqui, aquí está la sección relevante de man bash
:
Aquí Documentos
Este tipo de redirección instruye al shell para que lea la entrada desde el fuente actual hasta una línea que contenga sólo el delimitador (sin espacios en blanco al final). Todas las líneas leídas hasta ese momento son luego se usan como la entrada estándar para un comando.
El formato de aquí-documentos es:
<[-]palabra aquí-documento delimitador
No se realiza ninguna expansión de parámetros, sustitución de comandos, expansión aritmética o expansión de nombre de ruta se realiza en word. Si algún carácter de word está entre comillas, el delimitador es el resultado de la eliminación de comillas en word, y no se expanden las líneas del documento de aquí. Si la palabra es sin comillas, todas las líneas del documento de aquí se someten a la expansión del parámetro expansión, sustitución de comandos y expansión aritmética. En el último caso, la secuencia de caracteres \lt;nueva línea> se ignora, y \lt;. debe usarse para citar los caracteres \, $, y `.
O, usando sus marcadores EOF, necesita citar el marcador inicial para que la expansión no se haga:
#-----v---v------
cat <<'EOF' >> brightup.sh
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi
EOF
IHTH
Esto debería funcionar, acabo de probarlo y ha funcionado como se esperaba: no se ha producido ninguna expansión, sustitución o lo que sea.
cat <<< '
#!/bin/bash
curr=`cat /sys/class/backlight/intel_backlight/actual_brightness`
if [ $curr -lt 4477 ]; then
curr=$((curr+406));
echo $curr > /sys/class/backlight/intel_backlight/brightness;
fi' > file # use overwrite mode so that you don't keep on appending the same script to that file over and over again, unless that's what you want.
Usando lo siguiente también funciona.
cat <<< ' > file
... code ...'
Además, vale la pena señalar que cuando se utilizan heredocs, como << EOF
, la sustitución y la expansión de variables y similares tienen lugar. Así que haciendo algo como esto
cat << EOF > file
cd "$HOME"
echo "$PWD" # echo the current path
EOF
siempre resultará en la expansión de las variables $HOME
y $PWD
. Así que si su directorio de inicio es /home/foobar
y la ruta actual es /home/foobar/bin
, file
se verá así:
cd "/home/foobar"
echo "/home/foobar/bin"
en lugar del esperado:
cd "$HOME"
echo "$PWD"