Piping to the head causes a pipe break in the shell script called from python

I have a command that I would execute to generate a random string:

var=`< /dev/urandom tr -dc _A-Zaz-0-9 | head -c8` 

When I run this command in an interactive bash session, I get absolutely no errors. But when I put this command in a script and run it as a script, I get a Broken pipe error, indicated by tr. I read several related topics, but still haven't answered why the script and interactive behavior are different, and is there any way to control it with shell options or with something else?

Edit I:

Regarding the comments provided, I found that the indication of faulty pipe errors can be controlled with:

  trap - SIGPIPE # to ignore errors 

and

  trap "" SIGPIPE # to display errors 

Edit II:

Well, I provided incorrect information about the playback conditions. Finally, it seems that the problem is with the python shell that called the script using os.system ():

  python -c "import os; os.system('sh -c \"< /dev/urandom tr -dc _A-Zaz-0-9 | head -c8\"')" 

The above line gives broken pipe errors regardless of the OS used.

Edit III:

This section was discussed here: https://mail.python.org/pipermail/python-dev/2005-September/056341.html

+5
source share
2 answers

If one of the parent processes is a sigpipe trap, then the pipeline inherits the ignore signal location, which will cause this problem that you are facing.

This can be (safely) reproduced with:

 ( trap '' pipe; var=`< /dev/urandom tr -dc _A-Zaz-0-9 | head -c8 ) 

Usually, the head -c8 executes pretty soon, after which its stdin closes. Since he stdin is a pipe connected to stdout from tr , now it makes no sense to write tr to his stdout . When he tries, the system will kill him with a sigpipe . If tr ignores this signal or inherits the ignore ( SIG_IGN ) location for this signal from its parent. Then a write to tr broken stdout will simply cause a regular error and set errno to EPIPE , at which point tr will most likely be pulled together and output that error to its stderr and exit.

+4
source

This answer gives a good summary of the piping problem from Python to head and shows some workarounds.

fooobar.com/questions/100989 / ...

+1
source

Source: https://habr.com/ru/post/1233260/


All Articles