2014-12-15 4 views
1

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

Скажем, я хотел создать псевдоним в Баше, который тонко изменить любую команду вошел в командной строке в ту же команду, но в конечном итоге пропустили через tac, чтобы отменить окончательный вывод. Несколько примеров того, что я пытаюсь сделать:

ls ---> ls | tac 
ls -la ---> ls -la | tac 
tail ./foo | grep 'bar' ---> tail ./foo | grep 'bar' | tac 

Есть ли способ создать псевдоним, или какие-то другие средства, которые будут добавлять | tac к концу каждого/каждая команда вводится без дополнительного вмешательства ? Дополнительное внимание уделяется идеям, которые легко спрятать в bashrc. ;)

+2

Псевдоним неправильный инструмент для этой работы. Я бы использовал ловушку DEBUG. –

ответ

1

bash не поддерживает модификацию команд таким образом. Тем не менее, он позволяет перенаправлять стандартный вывод для самой оболочки, которую каждая команда будет наследовать. Добавьте к этому .bashrc:

exec > >(tac) 
+0

Хороший звонок - но как вы получите обычное буферизацию здесь? –

+1

(Я также не уверен, что прямое утверждение «не поддерживает» является точным: ловушка DEBUG может запускать собственную версию команды, а затем подавлять оригинал). –

+1

Это приводит к исчезновению всех выходных данных. –

4

Это не гарантируется побочный эффект свободной, но это, вероятно, здравомыслящий первый срез:

reverse_command() { 
    # C check the number of entries in the `BASH_SOURCE` array to ensure that it's empty 
    # ...(meaning an interactive command). 
    if ((${#BASH_SOURCE[@]} <= 1)); then 
    # For an interactive command, take its text, tack on `| tac`, and evaluate 
    eval "${BASH_COMMAND} | tac" 
    # ...then return false to suppress the non-reversed version. 
    false 
    else 
    # for a noninteractive command, return true to run the original unmodified 
    true 
    fi 
} 

# turn on extended DEBUG hook behavior (necessary to suppress original commands). 
shopt -s extdebug 

# install our trap 
trap reverse_command DEBUG 
+0

Код работает при вводе _directly_ в интерактивной оболочке, но если вы поместите его в' ~/.bashrc' или '~/.bash_profile' (как это может быть сделано для того, чтобы шутка была эффективной),' reverse_command() 'увидит _enclosing script_ в' $ {BASH_SOURCE [0]} 'и' $ {# BASH_SOURCE [@]} 'будет _1_, поэтому условное выражение должно читать' (($ {# BASH_SOURCE [@]} = = 1)) в этом случае. – mklement0

+0

В качестве второстепенной достопримечательности bash 3.2.53 создает разбитый вывод с 'cat <<< $ 'line 1 \ nline 2 \ nline 3'', потому что' $ BASH_COMMAND' неверно описывает его как 'cat <<< $' \ 'строка 1 \ nline 2 \ nline 3 \' ''. Это было зафиксировано как минимум (по крайней мере) bash 4.3.30. – mklement0

+0

(комментарии Чарльза относятся к удаленному, ошибочному диагнозу. Комментарий 'exit' связан с тем, что вы не сможете использовать его для выхода из такой оболочки, потому что команда будет выполняться в подоболочке. Наконец, общий совет: Чтобы этот код работал на OSX и FreeBSD, используйте 'tail -r' вместо' tac'.) – mklement0

Смежные вопросы