В C-программе я могу написать argv [0], и новое имя отображается в списке ps.
Как это сделать в bash?
В C-программе я могу написать argv [0], и новое имя отображается в списке ps.
Как это сделать в bash?
У меня была возможность перейти через источник для bash, и не похоже, что есть поддержка для записи в argv [0].
Это можно сделать при запуске новой программы через exec -a <newname>
.
Только для записи, хотя это точно не соответствует исходному вопросу о посте, этот вопрос тривиально связан с zsh
:
ARGV0=emacs nethack
( exec -a foo bash -c 'echo $0' )
Я предполагаю, что у вас есть оболочка script, которую вы хотите выполнить так, что сам процесс script имеет новый argv[0]
. Например (я тестировал это только в bash, поэтому я использую это, но это может работать в другом месте).
#!/bin/bash
echo "process $$ here, first arg was $1"
ps -p $$
Результат будет примерно таким:
$ ./script arg1
process 70637 here, first arg was arg1
PID TTY TIME CMD
70637 ttys003 0:00.00 /bin/bash ./script arg1
Итак, ps
показывает оболочку /bin/bash
в этом случае. Теперь попробуйте свою интерактивную оболочку exec -a
, но в подоболочке, чтобы вы не сдули интерактивную оболочку:
$ (exec -a MyScript ./script arg1)
process 70936 here, first arg was arg1
PID TTY TIME CMD
70936 ttys008 0:00.00 /bin/bash /path/to/script arg1
Пункты, показывая /bin/bash
. что случилось? Вероятно, exec -a
установил argv[0]
, но затем появился новый экземпляр bash, потому что операционная система читала #!/bin/bash
в верхней части вашего script. Хорошо, что, если мы каким-то образом выполним exec'ing внутри script? Во-первых, нам нужно каким-то образом определить, является ли это "первым" выполнением экземпляра script или второго экземпляра exec
ed, иначе второй экземпляр будет выполняться снова и снова и снова в бесконечном цикле. Далее, нам нужно, чтобы исполняемый файл не был файлом с линией #!/bin/bash
вверху, чтобы предотвратить изменение ОС нашего желаемого параметра argv [0]. Здесь моя попытка:
$ cat ./script
#!/bin/bash
__second_instance="__second_instance_$$"
[[ -z ${!__second_instance} ]] && {
declare -x "__second_instance_$$=true"
exec -a MyScript "$SHELL" "$0" "[email protected]"
}
echo "process $$ here, first arg was $1"
ps -p $$
Благодаря этому ответу, я сначала тестирую переменную окружения __second_instance_$$
на основе PID (который не изменяется через exec
), так что это не будет сталкиваться с другими сценариями, используя эту технику. Если он пуст, я предполагаю, что это первый экземпляр, и я экспортирую эту переменную среды, а затем exec. Но, что важно, я не выполняю этот script, но я выполняю двоичный код оболочки напрямую, с этим script ($0
) в качестве аргумента, передавая все остальные аргументы ([email protected]
). Переменная среды - это немного взлома.
Теперь это результат:
$ ./script arg1
process 71143 here, first arg was arg1
PID TTY TIME CMD
71143 ttys008 0:00.01 MyScript ./script arg1
Это почти что. argv[0]
MyScript
, как я хочу, но там есть дополнительный arg ./script
, который является следствием выполнения оболочки напрямую (а не через обработку ОС #!
). К сожалению, я не знаю, как это лучше.
Я просто добавлю, что это должно быть возможно во время выполнения, по крайней мере в некоторых средах. Присвоение $0 в perl на linux действительно меняет то, что появляется в ps. Однако я не знаю, как это реализовано. Если я смогу узнать, я обновлю это.
изменить: Основываясь на том, как это делает perl, это нетривиально. Я сомневаюсь, что во время выполнения есть какой-либо bask, но не знаю точно. Вы можете увидеть как perl устанавливает имя процесса во время выполнения.
Скопируйте исполняемый файл bash на другое имя.
Вы можете сделать это в самой script...
cp /bin/bash ./new-name
PATH=$PATH:.
exec new-name $0
Если вы пытаетесь притвориться, что вы не оболочка script, вы можете переименовать сам script в нечто классное или даже "" (одно пространство), поэтому
exec new-name " "
Выполняет bash ваш script и появляется в списке ps как только new-name
.
ОК, поэтому вызов script "" - очень плохая идея:)
В принципе, чтобы изменить имя
bash script
переименуйте bash и переименуйте script.
Если вы беспокоитесь, как мистер Макдум. по-видимому, о копировании двоичного файла в новое имя (что абсолютно безопасно), вы также можете создать символическую ссылку
ln -s /bin/bash ./MyFunkyName
./MyFunkyName
Таким образом, символическая ссылка - это то, что появляется в списке ps. (снова используйте PATH = $PATH:. если вы не хотите./)