LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-11-2021, 09:35 AM   #1
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Rep: Reputation: 19
env shebang enters infinite loop


Code:
$ cat shebang.sh 
#!/usr/bin/env hisvar=8 /bin/bash 

echo hisvar=$hisvar
$ ./shebang.sh 
^C
This enters an infinite loop. Why?!
 
Old 12-11-2021, 09:59 AM   #2
HappyTux
Senior Member
 
Registered: Mar 2003
Location: Nova Scotia, Canada
Distribution: Debian AMD64
Posts: 4,170

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by doru View Post
Code:
$ cat shebang.sh 
#!/usr/bin/env hisvar=8 /bin/bash 

echo hisvar=$hisvar
$ ./shebang.sh 
^C
This enters an infinite loop. Why?!
According to shell check the shebang is wrong and you have undeclared variable. I modified it to actually use bash as intended and put the variable in a correct place and it works fine. Oh and it said at one point to double quote the $hisvar as well to have zero issues with it, though that disappeared when I put my version in it.

Code:
zeus@bullseye-raspi:~$ nano shebang.sh
zeus@bullseye-raspi:~$ chmod +x shebang.sh
zeus@bullseye-raspi:~$ ./shebang.sh 
^C
zeus@bullseye-raspi:~$ nano shebang.sh
zeus@bullseye-raspi:~$ ./shebang.sh 
hisvar=8
zeus@bullseye-raspi:~$ cat shebang.sh 
#!/bin/bash 
hisvar=8
echo hisvar=$hisvar
https://www.shellcheck.net/
 
1 members found this post helpful.
Old 12-11-2021, 10:05 AM   #3
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
You forgot -S / --split-string. Traditional shebang allows only one parameter. If you want more, you have to use env -S.

And anyway, /bin/bash as an argument to env makes no sense whatsoever. You use an env shebang when you don't know the path to Bash.

Last edited by shruggy; 12-11-2021 at 10:09 AM.
 
2 members found this post helpful.
Old 12-11-2021, 11:00 AM   #4
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by shruggy View Post
You forgot -S / --split-string. Traditional shebang allows only one parameter. If you want more, you have to use env -S.

And anyway, /bin/bash as an argument to env makes no sense whatsoever. You use an env shebang when you don't know the path to Bash.
Thanks, excellent reference!
Do you have any idea why the infinite loop?
 
Old 12-11-2021, 11:19 AM   #5
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Well, #!/usr/bin/env hisvar=8 /bin/bash is treated as
Code:
env hisvar='8 /bin/bash'
i.e. assigning a variable without running any command. When you run it on the command line it will just print the environment. But when you're calling it from a shebang it will try to run it like this
Code:
env hisvar='8 /bin/bash' ./shebang.sh
which will then translate to
Code:
env hisvar='8 /bin/bash' env hisvar='8 /bin/bash' ./shebang.sh
and so on.

Contrast that with the shebang line
Code:
#!/usr/bin/env -S hisvar=8 /bin/bash
which will be run as
Code:
env hisvar=8 /bin/bash ./shebang.sh
There are commands other than env that would enter the infinite loop for the same reason. The most obvious example is sudo:
Code:
#!/usr/bin/sudo hisvar=8 /bin/bash

Last edited by shruggy; 12-11-2021 at 11:48 AM.
 
2 members found this post helpful.
Old 12-15-2021, 07:41 AM   #6
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by shruggy View Post
Well, #!/usr/bin/env hisvar=8 /bin/bash is treated as
Code:
env hisvar='8 /bin/bash'
i.e. assigning a variable without running any command. When you run it on the command line it will just print the environment. But when you're calling it from a shebang it will try to run it like this
Code:
env hisvar='8 /bin/bash' ./shebang.sh
which will then translate to
Code:
env hisvar='8 /bin/bash' env hisvar='8 /bin/bash' ./shebang.sh
and so on.
shebang.sh, which was intended as an argument to bash, now becomes a command. This should happen for both
Code:
#!/usr/bin/bash
and
Code:
#!/usr/bin/env
but it happens only for the second. Why?

Do you know why
Code:
$ env -S 'OLDUSER=${USER} sh -c echo\ OLDUSER=\$OLDUSER'
env: invalid sequence '\ ' in -S
and they needed to do this
Code:
$ env -S 'OLDUSER=${USER} sh -c "echo\_OLDUSER=\$OLDUSER"'
OLDUSER=user
'\_' inside double quotes is replaced by a space

Last edited by doru; 12-15-2021 at 08:05 AM.
 
Old 12-15-2021, 07:52 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,039

Rep: Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347
Code:
env -S OLDUSER=${USER} sh -c 'echo OLDUSER=$OLDUSER'
 
Old 12-15-2021, 07:59 AM   #8
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by pan64 View Post
Code:
env -S OLDUSER=${USER} sh -c 'echo OLDUSER=$OLDUSER'
-S is redundant for that.
 
Old 12-15-2021, 08:18 AM   #9
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Quote:
Originally Posted by doru View Post
they needed to do this
Strictly speaking, they don't need it here:
Code:
env -S 'OLDUSER=${USER} sh -c "echo OLDUSER=\$OLDUSER"'
should work as well. You can always check how the string is going to be parsed with -v:
Code:
env -vS 'OLDUSER=${USER} sh -c "echo OLDUSER=\$OLDUSER"'
 
Old 12-15-2021, 09:17 AM   #10
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by shruggy View Post
Strictly speaking, they don't need it here:
Code:
env -S 'OLDUSER=${USER} sh -c "echo OLDUSER=\$OLDUSER"'
should work as well. You can always check how the string is going to be parsed with -v:
Code:
env -vS 'OLDUSER=${USER} sh -c "echo OLDUSER=\$OLDUSER"'
I edited my reply here: https://www.linuxquestions.org/quest...8/#post6309691

These old pieces of code can be quite confusing.
 
Old 12-15-2021, 09:40 AM   #11
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Quote:
Originally Posted by doru View Post
shebang.sh, which was intended as an argument to bash, now becomes a command. This should happen for both
Code:
#!/usr/bin/bash
and
Code:
#!/usr/bin/env
but it happens only for the second. Why?
No. This shouldn't happen for both. Bash expects a script as an argument, passing a variable instead would end in an error, you wouldn't get an infinite loop.
 
Old 12-15-2021, 12:12 PM   #12
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by shruggy View Post
No. This shouldn't happen for both. Bash expects a script as an argument, passing a variable instead would end in an error, you wouldn't get an infinite loop.
You are right again, bash expects a script. env works for binaries and scripts.
But this is a script. I was not explicit enough.
Code:
$ cat bash.sh 
#!/usr/bin/bash
$ cat env.sh 
#!/usr/bin/env
$ ./bash.sh # exits immediately 
$ ./env.sh # infinite loop 
^C
I am missing something here.
 
Old 12-15-2021, 01:25 PM   #13
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
What are you missing? How is this situation different from the one described in #5?

Shebang instructs the system to pass the script as an argument to the command specified in the shebang.

So, when the system encounters a script with the shebang #!/usr/bin/bash, it will be passed as an argument to /usr/bin/bash. Like this
Code:
/usr/bin/bash ./bash.sh
As the script is empty (for Bash, shebang is just a comment as any other), it does nothing.

And when the system encounters a script with the shebang #!/usr/bin/env, it will be passed as an argument to /usr/bin/env. Like this
Code:
/usr/bin/env ./env.sh
As the script is executable and the path to it is specified, env just tries to execute the script as if ./env.sh were specified at the command prompt. But this is the script with a shebang, so the system calls the program specified in the shebang (env) and passes it the script as argument for execution. And the whole process repeats itself. Over and over again.
 
1 members found this post helpful.
Old 12-15-2021, 02:44 PM   #14
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
./shebang.sh with
#!/usr/bin/bash

transforms to
/usr/bin/bash ./shebang.sh
And bash sees the shebang as a comment in the script.

./shebang.sh with
#!/usr/bin/env

transforms to
/usr/bin/env ./shebang.sh
And env does nothing (or sets an environment variable) then invokes
./shebang.sh

that again finds the shebang...
resulting in a loop.
 
1 members found this post helpful.
Old 12-16-2021, 03:01 AM   #15
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by shruggy View Post
What are you missing? How is this situation different from the one described in #5?

Shebang instructs the system to pass the script as an argument to the command specified in the shebang.
Quote:
Originally Posted by MadeInGermany View Post
bash sees the shebang as a comment in the script.
This is the piece of information I was missing.

The fact that bash ignores the shebang is even more shocking to me than the fact that bash does not run binaries. This may be done precisely to stop the recursion.

Thank you all for your kind help.

Last edited by doru; 12-16-2021 at 04:33 AM.
 
  


Reply

Tags
env, infinite, loop, script, shebang, variable



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] infinite loop that isnt infinite? frieza Programming 2 10-27-2010 02:16 PM
RPM dependency failure: /usr/bin/env instead of /bin/env anoosh3000 Linux - Software 1 04-10-2009 05:34 AM
fetchmail stuck in infinite loop Prommy Linux - Software 0 02-17-2004 08:15 AM
Sendmail build - infinite loop?? kstarks Linux - Software 0 10-02-2003 07:13 AM
How do i ping an address in Konsole w/ out an infinite loop?? vbp6us Linux - Networking 1 03-02-2003 04:26 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:38 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration