Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ls: terminated by signal 13 when using xargs

Tags:

find

xargs

I'm using the following command to delete four largest size files in a folder:

find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4 | xargs -d '\n' rm -f

It works fine, but from time to time throws broken pipe error:

xargs: ls: terminated by signal 13
like image 844
user1529918 Avatar asked Jan 06 '15 14:01

user1529918


3 Answers

I ran across a similar issue and found this thread on search for an answer:

Signal 13 means something is written to a pipe where nothing is read from anymore (e.g. see http://people.cs.pitt.edu/~alanjawi/cs449/code/shell/UnixSignals.htm ).

The point here is that the ls command as executed by xargs is still writing output when the following head command already got all the input it wants and closed its input-pipe. Thus it's safe to ignore, yet it's ugly. See also the accepted answer in https://superuser.com/questions/554855/how-can-i-fix-a-broken-pipe-error

like image 155
planetmaker Avatar answered Nov 02 '22 10:11

planetmaker


You are purposely terminating your program with head -n 4, which creates the broken pipe because you terminated it before the "caller" finished. Since this is expected by you, you can ignore the error by redirecting it to /dev/null which discards it:

find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4 | xargs -d '\n' rm -f 2>/dev/null

like image 44
David Espart Avatar answered Nov 02 '22 09:11

David Espart


I got the same error, "terminated by signal 13", under different circumstances and other answers here helped me work out the fix. I'd like to expand on the nature of the problem:

corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | ( read f && echo $f && grep 'def=' $f )
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
xargs: grep: terminated by signal 13

So here's the same error and I'd only get a single line of output when I knew there are numerous files that match what I'm looking for. The problem was that xargs is producing multiple lines of output and read is only consuming a single line before ending. xargs tries to write the rest of its results to one of the pipes but the receiving end has already quit and gone home. Hence, signal 13: Broken Pipe.

The fix was to consume all of xargs's output by looping - change read f && do_some_things (which reads one time only) to while read f; do do_some_things; done.

corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ **find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | while read f; do echo $f; grep 'def=' $f; done**
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
      def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
      def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
      def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
      def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"

This isn't exactly the same situation as OP's script - They wanted a part of the input and cut it off on purpose, I wanted the whole stream and cut it off by accident - but the shell semantics work out the same. Programs tend to be written to keep running until they have consumed all their input rather than test to see if their recipient is still listening.

like image 2
gws Avatar answered Nov 02 '22 11:11

gws