Jak napisać skrypt bash, który pobiera opcjonalne argumenty wejściowe?

Chcę, aby mój skrypt mógł przyjmować opcjonalne dane wejściowe,

Np. obecnie mój skrypt to

#!/bin/bash
somecommand foo

Ale chciałbym powiedzieć:

#!/bin/bash
somecommand  [ if $1 exists, $1, else, foo ]
Author: Amir, 2012-02-17

8 answers

Możesz użyć składni wartości domyślnej:

somecommand ${1:-foo}

Powyższe będzie, jak opisano w Bash Reference Manual - 3.5.3 rozszerzenie parametru powłoki [emfaza]:

Jeśli parametr jest unset lub null, rozszerzenie programu word jest zastępowane. W przeciwnym razie podstawia się wartość parametru.

Jeśli chcesz zastąpić wartość domyślną tylko wtedy, gdy parametr jest unset( ale nie jeśli jest null, np. nie jeśli jest pusty łańcuch), użyj tej składni zamiast:

somecommand ${1-foo}

Ponownie z podręcznika Bash Reference - 3.5.3 rozszerzenie parametrów powłoki:

Pominięcie dwukropka powoduje test tylko dla parametru, który nie jest ustawiony. Innymi słowy, jeśli dwukropek jest włączony, operator testuje istnienie obu parametrów i jego wartość nie jest null; jeśli dwukropek jest pominięty, operator testuje tylko istnienie.

 472
Author: Itay Perl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 20:45:53

Możesz ustawić wartość domyślną dla zmiennej w następujący sposób:

Somecommand.sh

#!/usr/bin/env bash

ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}

echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"

Oto kilka przykładów jak to działa:

$ ./somecommand.sh
foo
bar
1
Thu Mar 29 10:03:20 ADT 2018

$ ./somecommand.sh ez
ez
bar
1
Thu Mar 29 10:03:40 ADT 2018

$ ./somecommand.sh able was i
able
was
i
Thu Mar 29 10:03:54 ADT 2018

$ ./somecommand.sh "able was i"
able was i
bar
1
Thu Mar 29 10:04:01 ADT 2018

$ ./somecommand.sh "able was i" super
able was i
super
1
Thu Mar 29 10:04:10 ADT 2018

$ ./somecommand.sh "" "super duper"
foo
super duper
1
Thu Mar 29 10:05:04 ADT 2018

$ ./somecommand.sh "" "super duper" hi you
foo
super duper
hi
you
 180
Author: Brad Parks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 17:07:30
if [ ! -z $1 ] 
then 
    : # $1 was given
else
    : # $1 was not given
fi
 34
Author: Irit Katriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 18:38:47

Możesz sprawdzić liczbę argumentów za pomocą $#

#!/bin/bash
if [ $# -ge 1 ]
then
    $1
else
    foo
fi
 16
Author: Dennis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-02 23:38:57

Proszę nie zapominać, jeśli jego zmienna $1 .. $n aby użyć podstawienia

#!/bin/bash
NOW=$1
echo  ${NOW:-$(date +"%Y-%m-%d")}
 7
Author: hagen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-28 10:01:22

Dla opcjonalnego wielu argumentów , analogicznie do polecenia ls, które może pobierać jeden lub więcej plików lub domyślnie wypisuje wszystko w bieżącym katalogu:

if [ $# -ge 1 ]
then
    files="$@"
else
    files=*
fi
for f in $files
do
    echo "found $f"
done

Nie działa poprawnie dla plików ze spacjami w ścieżce, niestety. Jeszcze nie wymyśliłem, jak to zrobić.

 3
Author: Jesse Glick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-09 15:21:24

Możliwe jest użycie substytucji zmiennej w celu zastąpienia stałej wartości lub polecenia (np. date) dla argumentu. Odpowiedzi do tej pory skupiały się na stałych wartościach, ale to jest to, czego użyłem, aby date był opcjonalnym argumentem:

~$ sh co.sh
2017-01-05

~$ sh co.sh 2017-01-04
2017-01-04

~$ cat co.sh

DAY=${1:-$(date +%F -d "yesterday")}
echo $DAY
 1
Author: Garren S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 21:17:59

Pozwala na domyślną wartość dla opcjonalnego 1st arg i zachowuje wiele args.

 > cat mosh.sh
   set -- ${1:-xyz} ${@:2:$#} ; echo $*    
 > mosh.sh
   xyz
 > mosh.sh  1 2 3
   1 2 3 
 1
Author: mosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-26 14:17:42