0

I have a *.sh script that's missing the shebang from the first line. Can I fix it with sed?

voices
  • 1,272

2 Answers2

4

Insert (i) the shebang with sed, in place operation:

sed -i '1 i #!/bin/bash' file.sh

With backing up the original file with a .bak extension:

sed -i.bak '1 i #!/bin/bash' file.sh

Replace #!/bin/bash with actual shebang you want.

Example:

% cat foo.sh
echo foobar

% sed '1 i #!/bin/bash' foo.sh 
#!/bin/bash
echo foobar
heemayl
  • 56,300
2

Using bash and cat (not in-place):

cat <(echo '#!/bin/sh') foo.sh

Or in-place using GNU awk >= 4.1:

awk -i inplace 'BEGINFILE{print "#!/bin/sh"}{print}' foo.sh

voices
  • 1,272
rudimeier
  • 10,315
  • For the first one { echo '#! /bin/sh -'; cat foo.sh; } or echo '#! /bin/sh -' | cat - foo.sh would make it more straightforward (and portable) (and more efficient for the first one) IMO – Stéphane Chazelas Sep 28 '16 at 20:34
  • @Stéphane Chazelas: thx, regarding { echo '#! /bin/sh -'; cat foo.sh; }, this was my first version but I hate using cat (concatenate) for only one file. In zsh it would work like this { echo '#! /bin/sh -'; <foo.sh; }. Nothing similar is portable I guess. However I think I should remove my non-inplace version since OP wants to edit the file. – rudimeier Sep 28 '16 at 20:43
  • Note that zsh's <foo.sh actually calls pager < foo.sh – Stéphane Chazelas Sep 28 '16 at 20:59
  • @rudimeier Thanks for these alternative solutions. If the first one works, I could probably just add something like; >foo-1.sh to the end, no?. – voices Oct 03 '16 at 11:25
  • @tjt263 No, this does not work in general. See http://unix.stackexchange.com/questions/36261/can-i-read-and-write-to-the-same-file-in-linux-without-overwriting-it – rudimeier Oct 04 '16 at 09:55
  • @rudimeier It's writing to a different file. -1 – voices Oct 04 '16 at 13:36
  • Ah sorry I've misread it! – rudimeier Oct 04 '16 at 13:37