Reputation: 6080
I have two custom scripts to implement their own tasks, one for outputting some URLs (pretend as cat
command below) and another for receiving a URL to parse it via network requests (pretend as sleep
command below).
Here is the prototype:
Case 1:
cat urls.txt | xargs -I{} sleep 1 && echo "END: {}"
The output is END: {}
and the sleep
works.
Case 2:
cat urls.txt | xargs -I{} echo "BEGIN: {}" && sleep 1 && echo "END: {}"
The output is
BEGIN: https://www.example.com/1
BEGIN: https://www.example.com/2
BEGIN: https://www.example.com/3
END: {}
but it seems only sleep
1 second.
Q1: I'm a little confused, why are these outputs?
Q2: Are there any solutions to execute the full pipelined xargs
delay command for every cat
line output?
Upvotes: 0
Views: 100
Reputation: 6080
Thanks for shellter and UtLox's reminder, I found the xargs
is the key.
Here is my finding, the shell/zsh interpreter splits the sleep 5
and echo END: {}
as another serial of commands, so xargs
didn't receive my expected two &&
inline commands as one utility command and replace the {}
with value in the END
expression. This could be proved by xargs -t
.
cat urls.txt | xargs -I{} -t echo "BEGIN: {}" && sleep 1 && echo "END: {}"
Inspired by UtLox's the answer, I found I could join my expectation with sh -c
in xargs
.
cat urls.txt | xargs -I{} -P 5 sh -c 'echo "BEGIN: {}" && sleep 1 && echo "END: {}"'
For the -P 5
, it makes the utility commmand ran with max specified subprocesses in parallel mode to make use of most bandwide resources.
Done!
Upvotes: 1
Reputation: 4164
You can put the commands into a separate script:
worker.sh
#!/bin/bash
echo "BEGIN: $*" && sleep 1 && echo "END: $*"
set execute permission:
chmod +x worker.sh
and call it with xargs:
cat urls.txt | xargs -I{} ./worker.sh {}
output
BEGIN: https://www.example.com/1
END: https://www.example.com/1
BEGIN: https://www.example.com/2
END: https://www.example.com/2
BEGIN: https://www.example.com/3
END: https://www.example.com/3
Between BEGIN and END the script sleep for one second.
Upvotes: 2