Я отвечу только за Linux.
Удивительно, но в новых ядрах системный вызов ptrace
, который используется strace
для фактического выполнения трассировки, позволяет отслеживать процесс инициализации. На странице руководства сказано:
EPERM The specified process cannot be traced. This could be because
the tracer has insufficient privileges (the required capability
is CAP_SYS_PTRACE); unprivileged processes cannot trace pro‐
cesses that they cannot send signals to or those running set-
user-ID/set-group-ID programs, for obvious reasons. Alterna‐
tively, the process may already be being traced, or (on kernels
before 2.6.26) be init(8) (PID 1).
, что подразумевает, что начиная с версии 2.6.26, вы можете отслеживать init
, хотя, конечно, вы все еще должны быть root, чтобы сделать это. Бинарный файл strace
в моей системе позволяет мне отслеживать init
, и на самом деле я даже могу использовать gdb
для подключения к init
и уничтожения Это. (Когда я это сделал, система немедленно остановилась.)
ptrace
не может использоваться процессом для трассировки себя, поэтому, если strace
не проверит, он, тем не менее, завершится ошибкой на отслеживая себя. Следующая программа:
#include
#include
#include
int main() {
if (ptrace(PTRACE_ATTACH, getpid(), 0, 0) == -1) {
perror(NULL);
}
}
печатает Операция запрещена
( т.е. результат EPERM
). Ядро выполняет эту проверку в ptrace.c
:
retval = -EPERM;
if (unlikely(task->flags & PF_KTHREAD))
goto out;
if (same_thread_group(task, current)) // <-- this is the one
goto out;
Теперь два процесса strace
могут отслеживать друг друга; ядро этому не помешает, и вы сами можете наблюдать за результатом. Для меня последнее, что выводит первый процесс strace
(PID = 5882), это:
ptrace(PTRACE_SEIZE, 5882, 0, 0x11
, тогда как второй процесс strace
(PID = 5890) вообще ничего не печатает. ps
показывает оба процесса в состоянии t
, что, согласно странице руководства proc (5)
, означает, что трассировка остановлена.
Это происходит из-за того, что трассируемый объект останавливается всякий раз, когда он входит в системный вызов или выходит из него, а также всякий раз, когда ему собирается доставить сигнал (кроме SIGKILL
).
Предположим, что процесс 5882 уже отслеживает процесс 5890. Затем мы можем вывести следующую последовательность событий:
ptrace
, пытаясь отследить процесс 5882. Процесс 5890 входит в трассировку. -останавливаться. SIGCHLD
, чтобы сообщить ему, что его трассируемый процесс 5890 остановлен. (Процесс с остановленной трассировкой выглядит так, как если бы он получил сигнал `SIGTRAP.) ptrace (PTRACE_SYSCALL, 5890, ...)
, чтобы продолжить процесс 5890. ptrace (PTRACE_SEIZE, 5882, ...)
. Когда последний возвращается, процесс 5890 переходит в режим остановки трассировки. SIGCHLD
, поскольку его трассируемый объект только что снова остановился. Поскольку он отслеживается, получение сигнала приводит к переходу к остановке трассировки. Теперь оба процесса остановлены. Конец.
Как вы можете видеть из этого примера, ситуация, когда два процесса отслеживают друг друга, не создает никаких внутренних логических трудностей для ядра, вероятно, поэтому код ядра не содержит проверки, предотвращающей возникновение такой ситуации.Просто бывает не очень полезно, чтобы два процесса отслеживали друг друга.
Мне кажется, вы используете неправильный тип цитат ("" )против (""):
echo $PATH
/home/anon/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
sudo bash -c 'echo \$0 this is a test' >/opt/test.sh;sudo chmod +x /opt/test.sh
anon@masterbox:~$ export PATH=“$PATH:/opt”
anon@masterbox:~$ test.sh
bash: test.sh: command not found
anon@masterbox:~$..bashrc
anon@masterbox:~$ export PATH="$PATH:/opt"
anon@masterbox:~$ test.sh
/opt/test.sh this is a test
anon@masterbox:~$
Изменить :Чтобы еще больше прояснить проблему, посмотрите, что произойдет, если я сделаю это по-вашему:
$ echo $PATH
# this is correct
/home/anon/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
$ export PATH=“$PATH:/opt”
$ echo $PATH
# this is incorrect
“/home/anon/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/opt”
$
Таким образом, Bash неправильно интерпретирует переменную PATH. Кавычки Unicode не работают таким образом в системах unix. Надеюсь, что это ответ на ваш вопрос.
Для меня есть 2 группы файлов, в которых можно определить $PATH:
1. Файлы bash, такие как ~/.profile, ~/.bashrc и их эквиваленты /etc
2. /etc/enviroment и ~/.pam _окружение
Некоторые из этих мест являются глобальными для всех пользователей, а некоторые зависят от пользователя.
Я рекомендую вам написать команду, которую вы использовали, в одном из этих мест, помня, что файлы с~работают только с пользователем, который использует домашний каталог, в котором находится файл.
Также помните, если вы пропишете путь, например, ~/.bashrc, будучи, например, пользователем Robertus, если вы измените на root, путь изменится на root, следуя его собственному ~/.bashrc и компании..
Надеюсь, мой ответ был вам полезен
Работает ли корова, если запустить ее как :/opt/cow
? Если нет, проверьте режим файла «корова»; он должен иметь установленный исполняемый бит. Если это не так, используйте:chmod +x /opt/cow