Skip to main content
minor changes
Source Link
A.B
  • 39.6k
  • 2
  • 88
  • 134

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

That's the issue. The kernel will not execute such shell script, because it doesn't start with the mandatory #!/bin/bash telling the kernel to delegate the execution to the bash interpreter.

This very rarely happens because most tools will use a shell to execute a command if it didn't execute immediately. Here's an example when strace-ing perl to execute this command (while searching without success a commandtool that would make execution of the script fail immediately):

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error) execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

It attempted first to execute the script without interpreter in its first line and got:

ENOEXEC (Exec format error) 

and then tried again by inserting a shell before so it works. Here /bin/sh, is not even bash in this environment, so if the script includes bash constructs, it would subtly misbehave later.

Had /tmp/debug.sh be this (and with the u+rx perms):

#!/bin/bash echo "TESTING" >> /tmp/debuglog.txt 

then:

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

Then /tmp/debug.sh would have be executed directly by the kernel (which would have actually defered the execution to /bin/bash).

udev doesn't attempt to do this, so it requires a valid binary for the kernel as first file in the command. Either supplying it directly, either by supplying a script which is an adequate executable from the point of view of the kernel by starting with the #!/path/to/interpreter line.

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

That's the issue. The kernel will not execute such shell script, because it doesn't start with the mandatory #!/bin/bash telling the kernel to delegate the execution to the bash interpreter.

This very rarely happens because most tools will use a shell to execute a command if it didn't execute immediately. Here's an example when strace-ing perl to execute this command (while searching without success a command that would fail immediately):

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error) execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

It attempted first to execute the script without interpreter in its first line and got:

ENOEXEC (Exec format error) 

and then tried again by inserting a shell before so it works. Here /bin/sh, is not even bash, so if the script includes bash constructs, it would subtly misbehave later.

Had /tmp/debug.sh be this (and with the u+rx perms):

#!/bin/bash echo "TESTING" >> /tmp/debuglog.txt 

then:

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

Then /tmp/debug.sh would have be executed directly by the kernel (which would have actually defered the execution to /bin/bash).

udev doesn't attempt to do this, so it requires a valid binary for the kernel as first file in the command. Either supplying it directly, either by supplying an adequate executable from the point of view of the kernel starting with the #!/path/to/interpreter line.

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

That's the issue. The kernel will not execute such shell script, because it doesn't start with the mandatory #!/bin/bash telling the kernel to delegate the execution to the bash interpreter.

This very rarely happens because most tools will use a shell to execute a command if it didn't execute immediately. Here's an example when strace-ing perl to execute this command (while searching without success a tool that would make execution of the script fail immediately):

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error) execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

It attempted first to execute the script without interpreter in its first line and got:

ENOEXEC (Exec format error) 

and then tried again by inserting a shell before so it works. Here /bin/sh, is not even bash in this environment, so if the script includes bash constructs, it would subtly misbehave later.

Had /tmp/debug.sh be this (and with the u+rx perms):

#!/bin/bash echo "TESTING" >> /tmp/debuglog.txt 

then:

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

Then /tmp/debug.sh would have be executed directly by the kernel (which would have actually defered the execution to /bin/bash).

udev doesn't attempt to do this, so it requires a valid binary for the kernel as first file in the command. Either supplying it directly, either by supplying a script which is an adequate executable from the point of view of the kernel by starting with the #!/path/to/interpreter line.

Source Link
A.B
  • 39.6k
  • 2
  • 88
  • 134

The sole content of debug.sh is echo "TESTING" >> /tmp/debuglog.txt. Debuglog.txt is not being created.

That's the issue. The kernel will not execute such shell script, because it doesn't start with the mandatory #!/bin/bash telling the kernel to delegate the execution to the bash interpreter.

This very rarely happens because most tools will use a shell to execute a command if it didn't execute immediately. Here's an example when strace-ing perl to execute this command (while searching without success a command that would fail immediately):

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = -1 ENOEXEC (Exec format error) execve("/bin/sh", ["/bin/sh", "/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14452, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

It attempted first to execute the script without interpreter in its first line and got:

ENOEXEC (Exec format error) 

and then tried again by inserting a shell before so it works. Here /bin/sh, is not even bash, so if the script includes bash constructs, it would subtly misbehave later.

Had /tmp/debug.sh be this (and with the u+rx perms):

#!/bin/bash echo "TESTING" >> /tmp/debuglog.txt 

then:

$ strace -e execve perl -e 'exec ("/tmp/debug.sh");' execve("/usr/bin/perl", ["perl", "-e", "exec (\"/tmp/debug.sh\");"], [/* 15 vars */]) = 0 execve("/tmp/debug.sh", ["/tmp/debug.sh"], [/* 15 vars */]) = 0 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=14474, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- +++ exited with 0 +++ 

Then /tmp/debug.sh would have be executed directly by the kernel (which would have actually defered the execution to /bin/bash).

udev doesn't attempt to do this, so it requires a valid binary for the kernel as first file in the command. Either supplying it directly, either by supplying an adequate executable from the point of view of the kernel starting with the #!/path/to/interpreter line.