0

I would like a script that will show me the percentage of reserved blocks. If it can done another way, that is good.

This works if I manually make it executable. Can I make it executable from within the script itself?

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
fixit7
  • 3,127
  • 2
    I don't understand why you need to do this, or what all this code has to do with anything. Please [edit] the question to clarify. – wjandrea Jun 12 '18 at 20:20
  • @Jos OP didn’t write he wouldn’t execute the file, just not make it executable – that’s a difference. – dessert Jun 12 '18 at 21:19
  • I heavily edited my answer, please read the new “solution to your problem” section and see if it helps. – dessert Jun 13 '18 at 11:06

3 Answers3

5

Answer to your question

Of course that’s possible – but I’d not consider it good style. See below for a better solution.

If you run a shell and give it the script file as an argument it will execute it regardless of the absence of a shebang or any execution bit:

$ 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

If the script is executed multiple times you probably don’t want to call chmod without any need every time, so just test for the file being not executable:

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

As for your script, awk can do the whole thing in a single call:

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

I removed the sudo because you don’t use it in a script – run the whole script as root instead.

Solution to your problem

I read from your question that you’re bothered by the two steps necessary to set up a script. Let’s write a script that helps with that:

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

cat <&0 >"$1" makes cat read from stdin and write to the script file you give it as the first argument. Save this as e.g. makescript and make it executable with chmod +x /path/to/makescript. Now if you want to write a script, simply do it like that:

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

If you don’t want to type /path/to/makescript every time, define an alias like makescript=/path/to/makescript in your ~/.bash_aliases or ~/.bashrc or move it to a directory in your PATH.

Example run

$ 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

The sky is the limit.

dessert
  • 39,982
  • sudo is not too dangerous if used on a system where only one person has access. And I did not use my real password. :-) – fixit7 Jun 13 '18 at 01:04
  • 1
    @fixit7 bad habits tend to creep into actions where it is a problem. Good practice makes for a better user so if avoidable (and it always is) never use sudo in a script and never use a method where a password is visible. – Rinzwind Jun 13 '18 at 05:46
1

If you want to write the script's content and make it executable in the same command (sorta), you can simply add the chmod after the 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

I also took the liberty of simplifying your script a bit. You're already using awk, so you may as well do the whole thing there.

terdon
  • 100,812
  • gawk’s printf ignores l as a modifier – I wondered that when I simplified the script in basically the same way as you did, then I read the manual. :) – dessert Jun 13 '18 at 10:37
  • @dessert ah, thanks. Also, sorry, I admit I hadn't seen you'd done the same thing in your answer! – terdon Jun 13 '18 at 12:31
-2
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
αғsнιη
  • 35,660
fixit7
  • 3,127
  • 1
    Just curious, but why are you against editing this answer ? Pasted as is, the code looks unreadable when it's rendered, and # parts are missing. If you add 4 spaces to each line in the answer, then the website will apply autoformatting and avoid interpreting # as headings in the answer. Here's a suggested reading: https://stackoverflow.com/editing-help Hope this helps – Sergiy Kolodyazhnyy Jun 13 '18 at 01:48
  • 1
    I edited so it looks better. I want to be flexible. – fixit7 Jun 13 '18 at 01:59
  • 1
    Why are you adding this as an answer? This is exactly what you did before, isn’t it? – dessert Jun 13 '18 at 05:56
  • 1
    live better your life even if it's short. Also your this answer doesn't make your script executable by itself. – αғsнιη Jun 13 '18 at 09:37