1

In the example script below it is used to send to one or two email addresses, depending on which process is using the script. Do I need to add $3 to account for an additional email address or is $2 sufficient?

(
for file in /usr/app/tst/$1/MS_CASE_ST*.csv;
do
   uuencode ${file} $(basename ${file})
done
) | mailx -s "MS_CASE_ST*.csv file contains data. Please Research" $2 

An example of how the script, example.sh, is executed:

$ ./example.sh output email-1@web.com email-2@web.com
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Emile
  • 385

3 Answers3

7

$2 will always be only the second argument. $@ is an array of all the arguments, so if you want the second until the end you could do:

... | mailx -s "MS_CASE_ST*.csv file contains data.  Please research" "${@:2}"

the :2 is specifying an offset in the parameter expansion when expanding the $@ array

Eric Renouf
  • 18,431
  • 1
    Warning: This (using :2) will only work if bash is used to run the script. I appreciate that is usually will, but if the script has a shebang for /bin/sh, and sh has not been aliased to bash, it won't work. An alternative would be to use:
    output=$1; shift
    and then just use $@.
    – Bob Eager Jul 12 '17 at 17:17
  • @BobEager I took from the bash tag that it was probably a reasonable assumption, but it's good to call that out – Eric Renouf Jul 12 '17 at 17:18
  • The script has #!/bin/bash, does the shell running the script also have to be in bash? I'm pretty new but I feel like I said this right... in either case, sorry about that. – Emile Jul 12 '17 at 18:13
  • @Emile If you run it as path/to/script it will use the shebang line, as you described it would use bash regardless of the current shell. If you use sh script it will use sh regardless of what the shebang line says. If you use source script it will use your current shell regardless of what the shebang line says, so it all depends on how you run it – Eric Renouf Jul 12 '17 at 18:16
  • Thanks for the info... Using the autosys application we use the the /path/to/script format for the command. However, all the previous created scripts are named script.sh and within each script designates which shell. – Emile Jul 12 '17 at 18:23
  • *nix in general doesn't care about extensions, so you can have .sh if you like, or ignore it if you don't want it, no harm either way – Eric Renouf Jul 12 '17 at 18:24
1

To support multiple recipients with this particular script, use $1 as the path element, then shift this off from the list of positional parameters. Now the list, $@, contains only recipients.

#!/bin/bash

dir=$1
shift

shopt -s nullglob

for file in "/usr/app/tst/$dir/MS_CASE_ST"*.csv; do
    uuencode "$file" "$( basename "$file" )"  # or uuencode "$file" "${file##*/}"
done | mailx -s 'MS_CASE_ST*.csv file(s) contains data. Please Research' "$@"

A few notes:

  • Be careful and double quote any variable expansions, or you will have issues when a pathname contains spaces or filename globbing characters etc. (and single quote static strings).

  • Quoting $@ as "$@" ensures that it expands to individually quoted elements.

  • By setting the nullglob shell option in bash, we ensure that the globbing pattern that the loop uses expands to nothing if it does not match any existing pathname.

Kusalananda
  • 333,661
0

This question seems to be confusing shell arguments with the read command. They're different:

  1. The shell:

    set -- foo bar baz buzz zap bang ; echo $2
    

    Output is only the second word:

    bar
    
  2. The read command with two variable names:

    echo foo bar baz buzz zap bang | (read x y ; echo $y )
    

    Outputs everything including and past the 2nd word:

    bar baz buzz zap bang
    
agc
  • 7,223
  • I don't think it's confusing those things, it's looking at using the first argument as the directory to process and the rest as the recipient email addresses, then the output of the left side of the pipe will be the body of the mail message – Eric Renouf Jul 12 '17 at 22:37
  • @EricRenouf: I found agc’s “answer” a little confusing at first — and, in fact, I believe that this post is *not an answer* — but I believe that agc’s point is that the OP seemed to think that positional parameters worked like read arguments, as in “I only ever mentioned $1 and $2, so I expect $1 to be the first token and $2 to refer to everything else.” Of course, if it worked that way, then that wouldn’t work either, because $2 would be a single string, with all the email addresses concatenated. – G-Man Says 'Reinstate Monica' Jul 12 '17 at 22:49
  • @G-Man ah, I see that interpretation now. Thanks – Eric Renouf Jul 12 '17 at 22:54
  • 1
    @G-Man, Re "if it worked that way": since $2 is unquoted, the shell would not protect any whitespace, so if we imagine that mailx -s "MS_CASE_ST*.csv file contains data. Please Research" $2 used a read-like parse syntax then mailx would see as many arguments as $2 contained whitespace separated words. (If it worked that way, which of course it does not...) – agc Jul 13 '17 at 05:05
  • @agc: Yeah, I was waiting for somebody to call me out on that.   :-)   ⁠ – G-Man Says 'Reinstate Monica' Jul 13 '17 at 06:03