Hacer que el script sea ejecutable desde el propio script

Hacer que el script sea ejecutable desde el propio script

Me gustaría un script que me mostrara el porcentaje de bloques reservados. Si se puede hacer de otra manera, eso es bueno.

Esto funciona si lo hago ejecutable manualmente. ¿Puedo hacerlo ejecutable desde el propio script?

cat > somescript.sh << \EOF
#!/bin/bash

block_count=$(sudo tune2fs -l /dev/sda1 | awk '/^Block count:/ {print $NF}')
reserved_block_count=$(sudo tune2fs -l /dev/sda1 | awk '/^Reserved block count:/ {print $NF}')

perl -e 'printf("%.1lf%%\n", ($ARGV[0] * 100.0 ) / $ARGV[1])' "$reserved_block_count" "$block_count"
EOF

Respuesta1

Responde a tu pregunta

Por supuesto que es posible, pero no lo consideraría un buen estilo. Consulte a continuación para obtener una mejor solución.

Si ejecuta un shell y le proporciona el archivo de script como argumento, lo ejecutará independientemente de la ausencia de un shebang o de cualquier bit de ejecución:

$ cat no_script
chmod +x /path/to/no_script
$ ls -l no_script
-rw-rw-r-- 1 dessert dessert 24 Jun 12 22:59 script
$ bash no_script
$ ls -l no_script
-rwxrwxr-x 1 dessert dessert 24 Jun 12 22:59 script

Si el script se ejecuta varias veces, probablemente no desee llamarlo chmodsin necesidad cada vez, así que simplemente pruebe que el archivo no sea ejecutable:

[ ! -x /path/to/script ] && chmod +x /path/to/script

En cuanto a su script, awkpuede hacer todo en una sola llamada:

#!/bin/bash
tune2fs -l /dev/sda1 | awk '/^Block count:/{a=$NF}/^Reserved block count:/{b=$NF}END{printf "%.1f%%\n", b/a*100}'

Eliminé el sudoporque túno lo uses en un script– En su lugar, ejecute todo el script como root.

Solución a tu problema

Leí en tu pregunta que te molestan los dos pasos necesarios para configurar un script. Escribamos un script que ayude con eso:

#!/bin/bash
cat <&0 >"$1" &&
chmod +x "$1"

cat <&0 >"$1"hace catlectura desde stdin y escribe en el archivo de script que le proporciona como primer argumento. Guarde esto como, por ejemplo, makescripty hágalo ejecutable con chmod +x /path/to/makescript. Ahora, si quieres escribir un script, simplemente hazlo así:

/path/to/makescript /path/to/new/script <<EOF … EOF

Si no desea escribir /path/to/makescriptcada vez, defina un alias como makescript=/path/to/makescripten su ~/.bash_aliaseso ~/.bashrcmuévalo a un directorio en su PATH.

Ejecución de ejemplo

$ echo -e '#!/bin/bash\ncat <&0 >"$1" &&\nchmod +x "$1"' >makescript
$ chmod +x makescript 
$ ./makescript a_test_script <<EOF
> #!/bin/bash
> echo a script
> EOF
$ ls -l *script
-rwxrwxr-x 1 dessert dessert 26 Jun 13 12:44 a_test_script
-rwxrwxr-x 1 dessert dessert 43 Jun 13 12:44 makescript
$ ./a_test_script 
a script

El cielo es el limite.

Respuesta2

Si desea escribir el contenido del script y hacerlo ejecutable en el mismo comando (más o menos), simplemente puede agregar chmoddespués de cat:

$ cat > somescript.sh << \EOF && chmod a+x somescript.sh && sudo ./somescript.sh
#!/bin/bash
# Show percentage of reserved blocks
#
tune2fs -l /dev/sda5 |
     awk '/^Block count:/{bc=$NF}
          /^Reserved block count:/{rbc=$NF}
          END{printf "%.1f%%\n", (rbc*100)/bc}'
EOF

También me tomé la libertad de simplificar un poco tu guión. Ya estás usando awk, por lo que también puedes hacer todo allí.

Respuesta3

cat > somescript.sh << \EOF
#!/bin/bash
# Show percentage of reserved blocks

block_count=$(sudo tune2fs -l /dev/sda1 | awk '/^Block count:/ {print $NF}')
reserved_block_count=$(sudo tune2fs -l /dev/sda1 | awk '/^Reserved block count:/ {print $NF}')

perl -e 'printf("%.1lf%%\n", ($ARGV[0] * 100.0 ) / $ARGV[1])' "$reserved_block_count" "$block_count"
EOF

chmod +x somescript.sh

somescript.sh

información relacionada