Поддерживается классическая оболочка Bourne, а оболочка Bash и Korn по-прежнему поддерживается -k. Когда это действует, любые « dd-подобные» параметры команды в любом месте командной строки автоматически преобразуются в переменные среды, передаваемые команде:
$ set -k
$ echo a=1 b=2 c=3
$
Труднее убедить, что это переменные среды; Запуск этого работает для меня:
$ set -k
$ env | grep '^[a-z]=' # No environment a, b, c
$ bash -c 'echo "Args: $*" >&2; env' a=1 b=2 c=3 | grep '^[a-z]='
Args:
a=1
b=2
c=3
$ set +k
$ bash -c 'echo "Args: $*" >&2; env' a=1 b=2 c=3 | grep '^[a-z]='
Args: b=2 c=3
$
Первый env | grepдемонстрирует отсутствие переменных окружения с одной строчной буквой. Первый bashпоказывает, что в сценарий, выполняемый с помощью сценария, не передаются аргументы -c, а среда содержит три однобуквенные переменные. set +kОтменяет -k, и показывает , что та же команда теперь есть аргументы , переданные ему. (Это a=1было обработано как $0для сценария; вы можете доказать это тоже с соответствующим повторением.)
Это позволяет ./script.sh a=1 b=2добиться того, что задает вопрос, - то, что набор текста должен совпадать с набором a=1 b=2 ./script.sh.
Имейте в виду, что вы столкнетесь с проблемами, если попробуете такие приемы внутри скрипта:
if [ -z "$already_invoked_with_minus_k" ]
then set -k; exec "$0" "$@" already_invoked_with_minus_k=1
fi
Это "$@"лечится дословно; он не подвергается повторному анализу для поиска переменных стиля присваивания (как в, так bashи в ksh). Я старался:
#!/bin/bash
echo "BEFORE"
echo "Arguments:"
al "$@"
echo "Environment:"
env | grep -E '^([a-z]|already_invoked_with_minus_k)='
if [ -z "$already_invoked_with_minus_k" ]
then set -k; exec "$0" "$@" already_invoked_with_minus_k=1
fi
echo "AFTER"
echo "Arguments:"
al "$@"
echo "Environment:"
env | grep -E '^([a-z]|already_invoked_with_minus_k)='
unset already_invoked_with_minus_k
и только already_invoked_with_minus_kпеременная окружения установлена в execсценарии 'd.