Это потому, что set blah blah blah
на самом деле устанавливает параметры $1 ... $N
равными значениям аргументов, как показано в следующей записи:
pax$ echo $1
pax$ set $tool=hello ; echo $1
=hello
pax$ tool=xyzzy ; set $tool=hello ; echo $1
xyzzy=hello
(во второй команде $tool
не задано, поэтому оно отображается пустым).
В вашем случае set $tool=valgrind
устанавливает $1
на значение, которое вычисляет $tool=valgrind
, поэтому $@
меняется. не устанавливает переменную окружения tool
в valgrind
.
Если вы хотите установить переменную, просто используйте:
tool=valgrind
или, чтобы сделать его доступным для подоболочек:
export tool=valgrind
Команда set
используется для отображения содержимого среды или установки атрибутов и аргументов оболочки, а не именованных переменных. Если вы заглянете на справочную страницу man bash_builtins
, вы увидите бит, объясняющий это поведение (найдите описание set
):
Любые аргументы, оставшиеся после обработки параметров, обрабатываются как значения для позиционных параметров и присваиваются по порядку $1, $2, ... $n
.