Сделать скрипт исполняемым из самого скрипта

Сделать скрипт исполняемым из самого скрипта

Мне нужен скрипт, который покажет мне процент зарезервированных блоков. Если это можно сделать по-другому, это хорошо.

Это работает, если я вручную сделаю его исполняемым. Могу ли я сделать его исполняемым из самого скрипта?

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

решение1

Ответ на ваш вопрос

Конечно, это возможно – но я бы не считал это хорошим стилем. Ниже приведено лучшее решение.

Если запустить оболочку и передать ей файл скрипта в качестве аргумента, она выполнит его независимо от отсутствия shebang или любого бита выполнения:

$ 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

Если скрипт выполняется несколько раз, вы, вероятно, не захотите вызывать его chmodкаждый раз без необходимости, поэтому просто проверьте, является ли файл неисполняемым:

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

Что касается вашего скрипта, то awkон может сделать все за один вызов:

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

Я удалил, sudoпотому что тыне используйте это в сценарии– вместо этого запустите весь скрипт от имени пользователя root.

Решение вашей проблемы

Я прочитал в вашем вопросе, что вас беспокоят два шага, необходимые для настройки скрипта. Давайте напишем скрипт, который поможет с этим:

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

cat <&0 >"$1"делает catчтение из stdin и запись в файл скрипта, который вы указываете в качестве первого аргумента. Сохраните это как eg makescriptи сделайте его исполняемым с помощью chmod +x /path/to/makescript. Теперь, если вы хотите написать скрипт, просто сделайте это так:

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

Если вы не хотите вводить /path/to/makescriptкаждый раз, определите псевдоним, например, makescript=/path/to/makescriptили ~/.bash_aliases, ~/.bashrcили переместите его в каталог в вашем PATH.

Пример запуска

$ 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

Небо это предел.

решение2

Если вы хотите написать содержимое скрипта и сделать его исполняемым в той же команде (вроде как), вы можете просто добавить chmodпосле 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

Я также позволил себе немного упростить ваш скрипт. Вы уже используете awk, так что можете сделать все это там.

решение3

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

Связанный контент