Post History
Here's an alternative that is a one-liner drop-in for your existing script: eval set -- $(printf "%q\n" "$@" | sort -u) It works by escaping the initial arguments, piping the escaped arguments ...
Answer
#2: Post edited
- Here's an alternative that is a one-liner drop-in for your existing script:
- ```bash
- eval set -- $(printf "%q\n" "$@" | sort -u)
- ```
- It works by escaping the initial arguments, piping the escaped arguments through `sort -u` which discards any duplicates, and then unescaping them with `eval` (which is often unsafe when handling untrusted input, but in this case you've escaped everything first so it's okay). `set --` alters the command line arguments to be whatever follows, so after this line is run, your `$1`/`shift` loop will be reading from the filtered list.
Put that before your main loop and you're golden.
- Here's an alternative that is a one-liner drop-in for your existing script:
- ```bash
- eval set -- $(printf "%q\n" "$@" | sort -u)
- ```
- It works by escaping the initial arguments, piping the escaped arguments through `sort -u` which discards any duplicates, and then unescaping them with `eval` (which is often unsafe when handling untrusted input, but in this case you've escaped everything first so it's okay). `set --` alters the command line arguments to be whatever follows, so after this line is run, your `$1`/`shift` loop will be reading from the filtered list.
- Put that before your main loop and you're golden.
- (This does not remotely preserve argument order. The associative array approaches are better if you want the order of arguments to be the order in which the tasks are performed in the event of no duplicates. Since you said that doesn't matter to you, though, I thought this might be an approach worth considering.)
#1: Initial revision
Here's an alternative that is a one-liner drop-in for your existing script: ```bash eval set -- $(printf "%q\n" "$@" | sort -u) ``` It works by escaping the initial arguments, piping the escaped arguments through `sort -u` which discards any duplicates, and then unescaping them with `eval` (which is often unsafe when handling untrusted input, but in this case you've escaped everything first so it's okay). `set --` alters the command line arguments to be whatever follows, so after this line is run, your `$1`/`shift` loop will be reading from the filtered list. Put that before your main loop and you're golden.