I have a *.sh script that's missing the shebang from the first line. Can I fix it with sed?
Asked
Active
Viewed 2,601 times
2 Answers
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
- 54,820
- 8
- 124
- 141
-
Just curious, could you get it working on empty files too somehow? – rudimeier Sep 28 '16 at 19:40
-
@rudimeier Not of my knowledge, no. – heemayl Sep 28 '16 at 19:44
-
could do something like: if [[ -z $(
file.sh ; else sed '1 i #!/bin/bash' file.sh ; fi – Stephan Sep 28 '16 at 19:55 -
1@Stephan If you want like that, just do: `sed '1 i #!/bin/bash' file.sh || echo '#!/bin/bash' > file.sh` – heemayl Sep 28 '16 at 19:59
-
The downside to that approach is it will overwrite the contents of file.sh if the sed command fails for any reason (I/O issue, for example.) But yah, that's the general concept I was suggesting. – Stephan Sep 28 '16 at 20:01
-
@Stephan yes, just to get the idea going, and thousand other ways indeed for checking. – heemayl Sep 28 '16 at 20:05
-
BTW just noticed that executing a zero file just works. Don't know if actually executing the shell is important for the OP ;) – rudimeier Sep 28 '16 at 20:09
-
OP wants a shebang. Is this `bash` or `sh`? – rudimeier Sep 28 '16 at 20:11
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
-
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` (con**cat**enate) for only one file. In zsh it would work like this `{ echo '#! /bin/sh -';
– rudimeier Sep 28 '16 at 20:43 -
-
@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
-
-