findutils-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Findutils-patches] xargs problem


From: Bernhard Voelker
Subject: Re: [Findutils-patches] xargs problem
Date: Tue, 20 Dec 2016 08:46:03 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1

On 12/19/2016 11:23 PM, aws backup wrote:
> Hello, I hope I am in the right mailing list.
> 
> I would like to run following script:
> 
> *screen -dmS test2 /bin/bash -c "fswatch -0 -Ie ".*\.*$" -i ".*\.mp4$" 
> /path/to/folder | xargs -0 -n 1 -I
> {} filename=`basename {}`; terminal-notifier -message 's3cmd Upload $filename 
> started'; s3cmd put {} s3://bucket/ 2>&1 |
> tee /path/to/logfile | tee >(mail -s 'Upload $filename' address@hidden 
> <mailto:address@hidden>)
> && terminal-notifier -message 's3cmd Upload of $filename done'"*
> 
> Without the basename approach it works:
> 
> *screen -dmS test2 /bin/bash -c "fswatch -0 -Ie ".*\.*$" -i ".*\.mp4$" 
> /path/to/folder | xargs -0 -n 1 -I {} s3cmd
> put {} s3://bucket/"*
> 
> With the basename command I get following failure: 
> 
> *xargs: filename=basename {}:: No such file or directory*
> *
> *
> Where is my mistake?
> How can I make it work?

Let me re-indent this for you a bit including line numbers to see
how the shell reads this:

     1 screen -dmS test2 \
     2    /bin/bash -c "\

First of all, I suggest to put everything you want to have in the
screen(1) session into a shell script.  By this, you'd avoid the
ugly, neccessary quoting problem for all of the following.

     3      fswatch -0 -Ie ".*\.*$" -i ".*\.mp4$" /path/to/folder \
____________________________^^^^^^______^^^^^^^^

ouch, here you are leaving the quoting, so you might end up the shell
finding a glob match for your unquoted pattern.

     4        | xargs -0 -n 1 -I {} filename=`basename {}`;
______________________________________________^^^^^^^^^^^

I have to admit it is unclear to me why the basename(1) command
seems not to be executed before actually running the screen(1)
command, i.e., why you are getting the word "basename" in the
error message.  However, all you tell xargs(1) to do is to execute
  "filename=`basename {}`"
which is not a valid command; and xargs(1) tells you so:

> *xargs: filename=basename {}:: No such file or directory*

All the rest inside the outer shell command string are run after
the "fswatch ... | xargs ..." construct.

     5      terminal-notifier -message 's3cmd Upload $filename started';
     6      s3cmd put {} s3://bucket/ 2>&1 \
     7        | tee /path/to/logfile \
     8        | tee >(mail -s 'Upload $filename' address@hidden) \
     9            && terminal-notifier -message 's3cmd Upload of $filename 
done'"

Even if xargs(1) would run the assignment 'filename=...' as part of
shell code, the following code would not see the variable value "$filename".

I suggest:
* moving all you want to do into a shell script,
* moving all you want to do for one file argument of xargs in another shell
  script.
By this, you avoid confusion of what is "outer" and "inner".
Furthermore, I suggest:
* using "set -x" inside the shell script to see what it actually executes,
* using the --verbose switch of xargs(1) to see what it actually executes,

Hope this helps.

Have a nice day,
Berny



reply via email to

[Prev in Thread] Current Thread [Next in Thread]