Torne o script executável a partir do próprio script

Torne o script executável a partir do próprio script

Gostaria de um script que me mostrasse a porcentagem de blocos reservados. Se puder ser feito de outra maneira, isso é bom.

Isso funciona se eu torná-lo executável manualmente. Posso torná-lo executável a partir do próprio 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

Responder1

Responda à sua pergunta

Claro que isso é possível – mas eu não consideraria isso um bom estilo. Veja abaixo uma solução melhor.

Se você executar um shell e fornecer o arquivo de script como argumento, ele o executará independentemente da ausência de um shebang ou de qualquer bit de execução:

$ 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

Se o script for executado várias vezes, você provavelmente não desejará chamar chmodsem necessidade todas as vezes, então apenas teste se o arquivo não é executável:

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

Quanto ao seu script, awkvocê pode fazer tudo em uma única chamada:

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

Eu removi sudoporque vocênão use isso em um script– execute o script inteiro como root.

Solução para o seu problema

Li na sua pergunta que você está incomodado com as duas etapas necessárias para configurar um script. Vamos escrever um script que ajude nisso:

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

cat <&0 >"$1"faz cata leitura do stdin e a gravação no arquivo de script fornecido como primeiro argumento. Salve isso como, por exemplo, makescripte torne-o executável com chmod +x /path/to/makescript. Agora, se você quiser escrever um script, basta fazer assim:

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

Se você não quiser digitar /path/to/makescriptsempre, defina um alias como makescript=/path/to/makescriptno seu ~/.bash_aliasesou ~/.bashrcou mova-o para um diretório no seu arquivo PATH.

Exemplo de execução

$ 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

O céu é o limite.

Responder2

Se você quiser escrever o conteúdo do script e torná-lo executável no mesmo comando (mais ou menos), você pode simplesmente adicionar chmodapós 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

Também tomei a liberdade de simplificar um pouco o seu roteiro. Você já está usando awk, então é melhor fazer tudo lá.

Responder3

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

informação relacionada