Inputs argument for sh -c

I have doubts with the following command:

% find "$1" -name "*.html" -print0 | sort -zn | xargs -r -0 -n 1 sh -c 'echo "Dumping file: $2" >> "$1"; w3m "$2" >> "$1" 2>&1 ' sh "$2"

I have doubts in the input arguments value i.e. $0 , $1 , $2 ...

Step by step:
1.- % find "$1" -name "*.html" -print0 | ...
where:
- $1 is the name of the directory to search on
2.-

% ...| ... sh -c 'echo "Dumping file: $2" >> "$1"; w3m "$2" >> "$1" 2>&1' sh "$2"
where:
- $0 is sh -c
- $1 is the same as $1 in the step 1 :confused:??? Why???
- $2 is the htmlA
- $3 is the htmlB and so on with $4, $5 etc.

3.- Finally, .. sh "$2" makes a shift
The value in $3 will be now $2

Is my understanding correct? How is the value of $1 taken?

Thanks.

Not sure I understand your doubts, so please correct me should my interpretation be wrong.
Generally, you need to differentiate between positional parameters ($1, $2, ...) of the parent shell, and those that the subshell will see. Whatever you see in you above command line is the parent shell. So -
1.- Yes if the parent shell's first positional parameter holds a starting directory.

2.- the subshell started by sh will have a concoction of parent and sub shell's pos. parameters, depending on where and how you put single and / or double quotes. As this is difficult to tell from here, I'd start with a small subset of the commands and parameters to find out.

  1. Definitely NOT. shift ist the (builtin) command to shift positional parameters, sh will run a (bourne) shell as you did it in the xargs parameters.

If you think you have to use shift on the first sh -c , then

# change sh -c [your_command arg1 arg2 ...]  to
/bin/bash -c  [ your_command arg1 arg2 ] 

Rudi -

From: "xargs"

@jim mcnamara: Yes, understood, but doesn't s/he have sh as the command to run from xargs ?

Can someone give a source to start digging on this?

Furthermore. Can someone clarify the following:
$0 $1 $2 ... After the sh -c
$0: ?????
$1: name of the log file Why ??? From where is taken
$2: htmlA file
$3: htmlB file
...
:slight_smile:

Advanced Bash-Scripting Guide

They are not the same $0 $1 $2 variables as your own shell. They are in single quotes:

'echo "Dumping file: $2" >> "$1"; w3m "$2" >> "$1" 2>&1'

...so they are passed into sh -c unparsed, for it to handle.

I have my doubts about them too.

Nowhere, I think. There is a different form of shell code which I think they tried to adapt from:

echo 'echo arg1 $1 arg2 $2 arg3 $3 arg4 $4' | sh -s -- a b c d

This runs with the result:

arg1 a arg2 b arg3 c arg4 d

...But it runs code from standard input, not -c, so can't be used with xargs.

Someone tried to adapt that into a form suitable for xargs and didn't know what those arguments were for, so left them dangling.

Basically "sh -s" and "sh -c" do the opposite:

  • With sh -s, commands are read from the std input arguments are passed after the sh -s
  • With sh -c, arguments are read from the std input and commands are passed after the sh -c

Is my understanding correct?

sh -c does not take arguments from standard input, it does not take arguments at all. It takes the script from an argument.

What do you mean? $0, $1.. are set to a value according to what is executed in the previous command before pipe ? isn't it?

No, they're not. I don't think that code ever worked.