Найдите местоположение полученного сценария оболочки

В Вашем test.c файл Вы могли сбросить буферизированное использование данных (void)fflush(stdout); непосредственно после Вашего printf операторы.

    // in test.c
    printf("key %s %d ", (Event.type == key_release_type) ? "release" : "press  ", key->keycode);
    //fprintf(stderr,"key %s %d ", (Event.type == key_release_type) ? "release" : "press  ", key->keycode);
    //(void)fflush(NULL);
    (void)fflush(stdout);

На командной строке можно включить вывод с буфером строки путем выполнения xinput test 10 в псевдотерминале (имущество) с script команда.

script -q /dev/null xinput test 10 > file      # FreeBSD, Mac OS X
script -c "xinput test 10" /dev/null > file    # Linux
8
13.04.2017, 15:36
2 ответа

Местоположение полученного сценария не доступно, если Вы не используете оболочку, которая предлагает расширения спецификации POSIX. Можно протестировать это со следующим отрывком:

env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included

где included.sh содержит

echo "$0"
set

В ударе название полученного сценария находится в $BASH_SOURCE. В zsh (в zsh режиме эмуляции, не в sh или ksh режиме эмуляции), это находится в $0 (обратите внимание на это в функции, $0 имя функции вместо этого). В pdksh и тире, это не доступно. В ksh93 этот метод не показывает решение, но полный путь к включенному сценарию доступен как ${.sh.file}.

Если требование удара или ksh93 или zsh достаточно хорошо, можно использовать этот отрывок:

if [ -n "$BASH_SOURCE" ]; then
  this_script=$BASH_SOURCE
elif [ -n "$ZSH_VERSION" ]; then
  setopt function_argzero
  this_script=$0
elif eval '[[ -n ${.sh.file} ]]' 2>/dev/null; then
  eval 'this_script=${.sh.file}'
else
  echo 1>&2 "Unsupported shell. Please use bash, ksh93 or zsh."
  exit 2
fi

Можно попытаться предположить местоположение сценария путем взгляда на то, какие файлы оболочка имеет открытый. Экспериментально это, кажется, работает с тире и pdksh, но не с ударом или ksh93, которые, по крайней мере, для короткого сценария закрыли файл сценария к тому времени, когда они находят время для выполнения его.

  open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
  if [ -n "$open_file" ]; then
    # best guess: $open_file is this script
  fi

Сценарий не может быть файлом с дескриптором с самым высоким номером, если сценарий получен в сложном сценарии, который играл с перенаправлениями. Можно хотеть циклично выполниться через открытые файлы. Это, как гарантируют, не будет работать так или иначе. Единственный надежный способ определить местоположение полученного сценария состоит в том, чтобы использовать удар, ksh93 или zsh.


Если можно изменить интерфейс, то вместо того, чтобы получить сценарий, имейте сценарий, распечатывают отрывок оболочки, который будет передан eval в вызывающей стороне. Это - то, какие сценарии установить переменные среды обычно делают. Это позволяет Вашему сценарию быть записанным независимо от капризов оболочки вызывающей стороны и конфигурации оболочки.

#!/bin/sh
FOO_DIR=$(dirname -- "$0")
cat <<EOF
FOO_DIR='$(printf %s "$FOO_DIR" | sed "s/'/'\\''/g")'
PATH="\$PATH:$FOO_DIR/bin";
export FOO_DIR PATH
EOF

В вызывающей стороне: eval "`/path/to/setenv`"

7
27.01.2020, 20:12

В дополнение к ответу Жиля вы МОЖЕТЕ получить сценарий оболочки(if $0 = ash)через /proc/$$ interface. Я не знаю, насколько это точно, но /proc/$$/fd/11, кажется, всегда указывает на этот скрипт _с пеплом BusyBox.

Предоставление этого в качестве потенциального ответа тем, кто наткнется на эту страницу (, как и я ).

Последний ответ был удален --, поэтому моя претензия к этой работе проверена на 4 различных аппаратных платформах (x86, ARM, XLP и powerpc ). Все дают один и тот же ответ fd/11. Ссылка для чтения из /proc/$$/fd/11дает мой скрипт.

Энди

-1
27.01.2020, 20:12

Теги

Похожие вопросы