почему strace игнорирует мой псевдоним для rm?

8

У меня есть aliasнабор для моей rmкоманды. Если я запускаю aliasкоманду, это то, что я получаю в качестве вывода.

alias rm='rm -i'

Теперь, когда я запускаю rmкоманду, она работает нормально, как и ожидалось.

rm ramesh
rm: remove regular empty file `ramesh'? y

Теперь я изучал системные вызовы, которые вызываются при выполнении команды. Для этого я должен знать о straceкоманде из здесь , которые перечислены мне , что файлы, которые вызываются когда я выполнить какую - либо команду. Команда как ниже.

strace -ff -e trace=file rm ramesh 2>&1 

Команда работает отлично, за исключением того, что она игнорирует мои псевдонимы, которые у меня есть для моей rmкоманды. Удаляет файл без запроса пользователя.

Итак, straceигнорирует псевдонимы, как это? Если так, то почему?

РЕДАКТИРОВАТЬ:

Не уверен, если это что-то делать, но type -a rmдает мне вывод, как,

rm is aliased to `rm -i'
rm is /bin/rm

Так что же, /bin/rmв данном случае это рассматривается, поэтому пользователь не получает запрос перед удалением?

Рамеш
источник
3
straceне игнорирует псевдонимы, потому что это означало бы, что в первую очередь было что игнорировать. Псевдоним - это особенность оболочки. straceэто другая программа, и внутри straceпонятия псевдонимов не существует, поэтому игнорировать нечего. API, предоставляемый ядром для выполнения программ, также не имеет понятия псевдонимов, поэтому оболочка не может сказать strace об псевдонимах, даже если захочет.
Касперд
1
Если вы хотите straceиспользовать псевдоним, вам нужна straceоболочка, которая реализует псевдоним. Для этого есть несколько подходов: strace -p $$ &или strace bashили strace sh -c 'rm ramesh'(последний также игнорирует псевдоним, но по совершенно другой причине.)
kasperd

Ответы:

20

straceне работает rm -iпо той же причине, что и:

echo rm

не выводится rm -i.

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

В:

alias foo='whatever'
foo xxx

Снаряды расширяют это до:

whatever xxx

и это подвергается другому раунду интерпретации, в этом случае приводящему к выполнению whateverкоманды.

псевдонимы раскрываются только при нахождении в командной позиции (как первое слово командной строки).

zshподдерживает глобальные псевдонимы.

Вы могли бы сделать:

alias -g rm='rm -i'

Но вы не захотите, так как это будет означать, что:

echo rm

будет выводить, rm -iнапример.

Стефан Шазелас
источник
8

straceиспользует PATHпеременную окружения, чтобы найти отслеживаемую программу, а не выполнять ее через оболочку (что приведет к засорению вывода). Псевдоним оболочки - это не программа, это особенность оболочки, поэтому straceон игнорируется.

Бег strace strace rmдовольно поучителен, а также интересно рекурсивен.

отметка
источник
5

Псевдоним - это особенность вашей оболочки. Тем не менее, strace выполняет команду напрямую (используя execve, вероятно), что не включает оболочку. (Если strace выполнил данную команду через оболочку, то вывод strace будет содержать все системные вызовы выполнения оболочки, а не только те из интересующего процесса.)

Кроме того, когда вы запускаете strace rm ramesh, интерактивная оболочка не пытается заменить ваш псевдоним в аргументах на strace, потому что это будет ужасно сбивать с толку всех. Оболочка раскрывает только псевдонимы, которые появляются в первой позиции в командной строке.

Грег Хьюгилл
источник
2

Strace использует execve c functionтакие, как find command, однако find uses exec functionвы не можете использовать aliases, built-in shell commandили так далее.

Ты должен сделать:

strace /bin/rm -i ramesh
Персидский залив
источник
2

Чтобы основываться на ответе Стефана Шазеласа, если вы определите

alias strace="strace "

(с пробелом в конце), затем команда

strace rm ramesh

будет обработан как

strace rm -i ramesh

Но даже это будет работать только для первого слова после strace, поэтому оно не будет применяться непосредственно к вашему примеру (где у вас есть промежуточные варианты).  Но если вы определите

alias my_strace="strace -ff -e trace=file "

тогда

my_strace rm ramesh

будет обработан как

strace -ff -e trace=file rm -i ramesh
G-Man говорит: «Восстанови Монику»
источник
2

Здесь нет псевдонимов

Давайте предположим, что у нас есть определение псевдонима alias rm='rm -i'в нашем ~/.bashrc. Псевдоним добавляет опцию для запроса перед удалением каждого файла:

$ touch ./file
$ rm ./file
/bin/rm: remove regular empty file ‘./file’? 

Не вина, straceчто он не использовал псевдоним:
он не имеет ничего общего с псевдонимами.

В команде

$ strace -f -e file -o rm.strace rm ./file

Слова rmи ./fileпока являются просто аргументами для strace - оболочка не может раскрыть псевдоним rm, потому что не может знать, что strace будет использовать эти аргументы в качестве команды позже.

В общем, псевдонимы команд могут использоваться только там, где могут быть команды.

Псевдонимы - это особенность оболочки, и она straceвообще не использует оболочку при вызове команды из командной строки. exec()Вместо этого он использует команды и аргументы из собственной командной строки.

Внутри straceкоманда будет вызываться с чем-то похожим exec("rm", "file"), и exec()будет найдена /bin/rmв PATH - без использования оболочки.

Явная оболочка

Теперь, почему бы не включить в straceкоманду оболочку ?

$ touch ./file
$ strace -f -e file -o rm.strace bash -c 'rm ./file'
$ ls ./file
ls: cannot access ./file: No such file or directory

Хм ... это не сработало. rmпросто удалил файл, без -iподсказки.

Интерактивные псевдонимы

Псевдонимы обычно включены только в интерактивных оболочках, реальных командных строках в терминале.
С нашим примером псевдонима легко понять, почему это имеет смысл: если rm -iпсевдоним будет раскрыт внутри сценариев оболочки, они будут висеть в первую очередь, rmкогда никто не будет нажимать y.

Псевдонимы контролируются опцией оболочки expand_aliases. Мы могли бы установить опцию с bash +O expand_aliases -c .... Но этого недостаточно, потому что неинтерактивная оболочка также не будет читать ~/.bashrc. Это означает, что наш псевдоним не только отключен опцией, но и даже не определен.

Притворяться интерактивным

Простой способ обработки обеих частей - использовать параметр командной строки, -iчтобы оболочка притворилась, что она интерактивна:

$ touch ./file
$ strace -f -e file -o rm.strace bash -i -c 'rm ./file'
/bin/rm: remove regular empty file ‘./file’?

Наконец, -iпсевдоним был использован!

Обратите внимание, что вы обычно не используете оболочки, работающие с -iопцией для сценариев, даже если вы хотите, чтобы ваши псевдонимы были доступны, например.

Volker Siegel
источник