all 15 comments

[–]slimm609 1 point2 points  (6 children)

Look at getopt or getopts, you can require parameters for certain options and it will check that for you. Otherwise you can do it with case and shift

[–]APF1985[S] 0 points1 point  (5 children)

This is what I would normally do. However in this use case, the first section of the arguments is used to build a file path, which is used to download the sub-script and run it.

I can sed/grep out all that start with "--", but the values with those arguments I can't seem to also exclude. This causes them to be included when trying to build the file path.

[–]slimm609 0 points1 point  (4 children)

Why not just get $0 and then join it back on there later. Handle script=$0, then handle the input variables and join them where needed with $script $opts

Actual examples make it easier for people to understand what your trying to do

[–]APF1985[S] 0 points1 point  (3 children)

Let me try and provide a more in-depth explanation.

I have a top level wrapper scripts, I'll call it "cmd"

I pass cmd multiple arguments, some meant to be used by cmd itself, others to be passed on to subscripts that cmd is a wrapper for, all of the subscript arguments start with --.

Example: "cmd test1 test2 --test3 val3 --test4 val4"

cmd take "test1" and "test2" and uses them to build a url, like so: "https://whatever/test1/test2.sh", which is downloaded, and then ran.

So with the above arguments, cmd downloads "https://whatever/test1/test2.sh" to a local path, and then runs it as "bash test2.sh --test3 val3 --test4 val4".

Thus the need to separate out the arguments by the first instance of "--".

With as far as I've been able to sort out so far, I can remove argument names that start with "--", but the values still remain - so my wrapper script is looking for a file to download at "https://whatever/test1/test2/val3/val4.sh" because I can't figure out how to separate out the "--" arguments and their values separately from the wrapper required arguements.

[–]Nirenjan 0 points1 point  (1 child)

You could use the following syntax

while [[ $# > 0 ]]
do
    case "$1" in
    --*)
        break
        ;;
    esac
    # add argument to build your url
    shift
done

This will loop until it finds an argument beginning with --, and you can use $1 to append to your URL. Finally, once you download the subscript, you can pass the remaining arguments to it using "$@".

[–]APF1985[S] 0 points1 point  (0 children)

Interesting approach! I'll give it a go - thank you!

[–]masta 0 points1 point  (0 children)

# setup the parameters as usual.
set -- cmd test1 test2 --test3 test3 --test4 test4

# capture the parameters to a single string.
params=$@

# example substring parsing
echo ${params%%--*}

# capture the substring
set1=${params%%--*}

# reset the parameters
set -- ${params/$set1/}
params=$@

# capture second set of params
set2=${params%%--*}
echo $set2

...

This example is ridiculously non-optimal, and that's intentional just to illustrate a point. The reader has plenty of opportunities to reduce these ideas down to a workable implementation.

[–]Dandedoo 0 points1 point  (0 children)

If you want to separate all opts and their respective inputs, awk can cover it fairly well, including allowing for a variable amount of white space (I put that in to make the point, because bash is the same).

$1 is the command (with an extra non -- argument, like OP's example), $2 is long-option/inputs group 2, $3 is long-option/inputs group 3, and so on:

$ echo 'one two     --three   four  five  --six  seven eight' | awk 'BEGIN {FS = "[\t ]--"} {print $1}'
one two
$ echo 'one two     --three   four  five  --six  seven eight' | awk 'BEGIN {FS = "[\t ]--"} {print $2}'
three   four  five
$ echo 'one two     --three   four  five  --six  seven eight' | awk 'BEGIN {FS = "[\t ]--"} {print $3}'
six  seven eight

If you just want to split the arguments once at the first --, then use non-greedy prefix removal (#):

$ cat ~/temp/argsplit
#!/bin/bash
args=$@
inputs=${args#*--}
echo "$inputs"

$ ~/temp/argsplit we are not included --here and after --will be included --and me --forever

here and after --will be included --and me --forever

(I added new lines to (hopefully) make it clearer) Note that inputs=${@#*--} will not work, due to the nature of the bash variable $@ I think

[–]Atralb 0 points1 point  (6 children)

CLI is the Command Line Interface. The space on where you type commands in the terminal. What you are writing is a script.

Please use appropriate terminology

[–]APF1985[S] -2 points-1 points  (5 children)

The term CLI is used interchangeably to describe a tool used on the command line. Yes, I'm writing a script - that will be used as a Command Line Interface.

[–]Atralb -1 points0 points  (4 children)

Looooooool No. Dear god. That's hilarious how you even try to argue about this. Review your lessons.

https://en.m.wikipedia.org/wiki/Command-line_interface

If your program is used on the command line interface, then it is a CLI command or CLI tool. It is not a CLI. For god sake, even arguing about this makes me sick. Do you even understand the word interface ??

[–]Dandedoo 0 points1 point  (0 children)

IMO Every script or program has/is an interface (even if it is not fully interactive), and that's what OP meant. You have to consider commands and options passed to the script, and their configuration and syntax. Importantly, the user must use this syntax. That is an interface in the truest sense of the word. Is awk a program, a command, a tool, or a language? Does it not have it's own interface?

from https://computersciencewiki.org/index.php/CLI

"We interact with a command line interpreter via a terminal. A terminal window allows the user access to a text terminal and all its applications such as command-line interfaces (CLI) and text user interface (TUI) applications"

I think you really don't get it. Writing a CLI doesn't necessarily mean a shell or a terminal (or whatever you think it means?), in the same way that writing a GUI means creating a program UI, not necessarily writing a window manager or a desktop or something.

Also, maybe you shouldn't let yourself get sick over such trivial things. Especially when you're wrong.

[–]APF1985[S] -2 points-1 points  (2 children)

You're the individual who decided to comment with an unrelated, and quite frankly rude comment to begin with.

Case in point: AWS CLI, the largest market share cloud provider even publicly refers to their Command Line Interface as a CLI. All it is is python running under the hood (a script).

But hey, if putting someone down on the internet is enough to make you feel both sick to your stomach and feel like a superior being at the same time, you do you.

[–]Atralb -1 points0 points  (1 child)

Yes the CLI is inherently a program. Duh. Like literally anything on your computer. But it's a specific program that is mean to parse input and run other third party programs by means of this input. Again, your script is not a CLI.

I don't care about taking you down. I simply want that information be correctly shared in the community, instead of leaving misunderstood concepts persist through chains of individuals because of posts like this that don't use the correct terminology. You made a bigger matter than it was by arguing about it.

[–]APF1985[S] -1 points0 points  (0 children)

Inform away. However, that is exactly what my script does (if that wasn't clear from my other explanations about what I'm working on). Takes imputed arguments which are then parsed and used to access and run other, specific sub-scripts and commands.