I am attempting to write a script to list all the shebang lines in python files.

What I would like to do is

sudo bash -c 'for logf in $(find / -name "*.py"); do fgrep '#!/usr/bin' "$logf"; done'

This gives error bash: !/usr/bin': event not found. I understand why, although the meaning of the error is unclear.

The trouble is I can't figure out how to pass a string to bash which includes another string without command execution.

If I leave off the "#!" it works, but of course includes a number of other lines.

I have tried practically every combination of escape and string without success.

  • 1
    you could do this simply with the find command: find / -name "*.py" -exec fgrep '#!/usr/bin' {} \; -print
    – Ketan
    Feb 20, 2016 at 3:45
  • Escaping the # didn't help?
    – Jeff Schaller
    Feb 20, 2016 at 3:47
  • Do you want to make this command work (with minimal changes), or nest strings in general? Feb 20, 2016 at 4:04
  • @MichaelHomer At this stage I just want to make it work. I have had similar problems before, so would like to understand if there is a solution. I retried the plain command suggested by @Ketan with sudo, and this works. As I am only using a single command there is no need for the bash command.
    – Milliways
    Feb 20, 2016 at 4:14
  • 1
    fgrep '\\#\\!/usr/bin' worked for me.
    – jai_s
    Feb 20, 2016 at 4:14

1 Answer 1


Thanks to the comments I have 2 versions which work. Note I have made a couple of changes (to only find shebang at beginning of line) and to allow white space after shebang.

sudo bash -c 'for logf in $(find / -name "*.py"); do grep '^\\#\\!/usr/bin' "$logf"; done'

For some reason when I tried to allow white space after shebang I couldn't get it to work.

Even better (and simpler)

sudo find / -name "*.py" -exec grep '^#! */usr/bin' {} \;

Not the answer you're looking for? Browse other questions tagged .