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

Получить имя вызывающего скрипта в bash script

Предположим, у меня есть 3 сценария оболочки:

script_1.sh

#!/bin/bash
./script_3.sh

script_2.sh

#!/bin/bash
./script_3.sh

проблема в том, что в script_3.sh я хочу знать имя вызывающего скрипта.

так что я могу по-разному реагировать на каждого абонента, которого я поддерживаю

пожалуйста, не думайте, что я спрашиваю о $0 потому что $0 будет script_3 каждый раз, независимо от того, кто звонит

вот пример ввода с ожидаемым выводом

  • ./script_1.sh должен повторить script_1

  • ./script_2.sh должен повторить script_2

  • ./script_3.sh должен повторить user_name or root or anything to distinguish between the 3 cases?

Это возможно? и если возможно, как это можно сделать?

это будет добавлено в измененный скрипт rm... поэтому, когда я вызываю rm он что-то делает, и когда git или любой другой инструмент CLI используют rm это не влияет на изменение

4b9b3361

Ответ 1

Основываясь на ответе @user3100381, здесь приведена гораздо более простая команда для получения того же, что, на мой взгляд, должно быть довольно переносимым

PARENT_COMMAND=$(ps -o comm= $PPID)

Замените comm= на args= чтобы получить полную командную строку (команда + аргументы). Символ = используется для подавления заголовков.

См. Http://pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html.

Ответ 2

Переменная $PPID содержит идентификатор родительского процесса. Таким образом, вы можете разобрать вывод из ps, чтобы получить команду.

#!/bin/bash
PARENT_COMMAND=$(ps $PPID | tail -n 1 | awk "{print \$5}")

Ответ 3

В случае, если вы используете source вместо вызова/выполнения сценария, новый процесс не разветвляется, и поэтому решения с ps не будут работать надежно.

Используйте Баш встроенные caller в этом случае.

$ cat h.sh 
#! /bin/bash 
function warn_me() { 
    echo "[email protected]" 
    caller 
} 
$ cat g.sh 
#!/bin/bash 
source h.sh 
warn_me "Error: You didn't do something" 
$ . g.sh 
Error: You didn't do something 3 
g.sh
$

Источник

Ответ 4

Несколько полезных файлов хранятся в /proc/ $PPID здесь

  • /proc/*some_process_id*/exe Символьная ссылка на последнюю выполненную команду под * some_process_id *
  • /proc/*some_process_id*/cmdline Файл, содержащий последнюю выполненную команду в разделе * some_process_id * и аргументы, разделенные нуль-байтом

Итак, небольшое упрощение.

sed 's/\x0/ /g' "/proc/$PPID/cmdline"

Ответ 5

Если у вас /proc:

$(cat /proc/$PPID/comm)

Ответ 6

Основано на @JLanswer с более подробными объяснениями (единственная команда, которая работает для меня ()):

cat /proc/$PPID/comm

дает вам имя команды родителя

Если вы предпочитаете команду со всеми параметрами, то:

cat /proc/$PPID/cmdline

объяснения:

  • $PPID определяется оболочкой, это родительских процессов
  • в /proc/ вас есть несколько директорий с каждого процесса (). Затем, если вы cat/proc/$PPID/comm, вы выводите имя команды PID

Проверьте man proc

Ответ 7

Вы можете просто использовать приведенную ниже команду, чтобы избежать вызова cut/awk/sed:

ps --no-headers -o command $PPID

Если вы хотите только родительский и ни один из последующих процессов, вы можете использовать:

ps --no-headers -o command $PPID | cut -d' ' -f1

Ответ 8

Вы можете передать переменную script_3.sh, чтобы определить, как отвечать...

script_1.sh

#!/bin/bash
./script_3.sh script1

script_2.sh

#!/bin/bash
./script_3.sh script2

script_3.sh

#!/bin/bash
if [ $1 == 'script1' ] ; then
  echo "we were called from script1!"
elsif [ $1 == 'script2' ] ; then
  echo "we were called from script2!"
fi