Подтвердить что ты не робот

Как изменить argv0 в bash, поэтому команда появляется с другим именем в ps?

В C-программе я могу написать argv [0], и новое имя отображается в списке ps.

Как это сделать в bash?

4b9b3361

Ответ 1

У меня была возможность перейти через источник для bash, и не похоже, что есть поддержка для записи в argv [0].

Ответ 2

Это можно сделать при запуске новой программы через exec -a <newname>.

Ответ 3

Только для записи, хотя это точно не соответствует исходному вопросу о посте, этот вопрос тривиально связан с zsh:

ARGV0=emacs nethack

Ответ 4

( exec -a foo bash -c 'echo $0' ) 

Ответ 5

Я предполагаю, что у вас есть оболочка 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, который является следствием выполнения оболочки напрямую (а не через обработку ОС #!). К сожалению, я не знаю, как это лучше.

Ответ 6

Я просто добавлю, что это должно быть возможно во время выполнения, по крайней мере в некоторых средах. Присвоение $0 в perl на linux действительно меняет то, что появляется в ps. Однако я не знаю, как это реализовано. Если я смогу узнать, я обновлю это.

изменить: Основываясь на том, как это делает perl, это нетривиально. Я сомневаюсь, что во время выполнения есть какой-либо bask, но не знаю точно. Вы можете увидеть как perl устанавливает имя процесса во время выполнения.

Ответ 7

Скопируйте исполняемый файл 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:. если вы не хотите./)