使脚本在脚本本身内可执行

使脚本在脚本本身内可执行

我想要一个可以显示保留块百分比的脚本。如果可以用其他方式实现,那就太好了。

如果我手动使其可执行,则此方法有效。我可以从脚本内部使其可执行吗?

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

回答你的问题

当然可以,但我认为这不是好做法。请参阅下文以了解更好的解决方案。

如果你运行 shell 并将脚本文件作为参数传递给它,无论是否存在 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 读取并写入您作为第一个参数提供的脚本文件。将其保存为 egmakescript并使用 使其可执行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

相关内容