Примушування "доданого" псевдоніма до кожної команди


11

Чи можна насильно додати псевдонім синхронізації (через відсутність кращого способу його формулювання) до кожної команди bash?

Наприклад, я хотів би мати конкретного користувача, який щоразу, коли команда виконується, вона завжди завершена або dateдо, і після, або time.

Чи можливо це, і якщо так, то як?


Я дивився раніше, і не міг знайти спосіб зробити саме це. Як каже Калеб, ви можете використовувати його preexec, але ви не хочете запускати його всередині preexec(наприклад preexec() { time $1; }), тому що оболонка все ще працює після preexecповернення. Тож найкраще, що ми можемо зробити, - це щось подібне.
Мікель

@Mikel Я думаю, що ви можете використовувати цю preexec()функцію, щоб фактично обгортати все, що виконується, отримуючи команду, запускаючи її всередині функції, а потім повертаючи якусь помилку, щоб оболонка не продовжувала виконувати команду сама.
Калеб

Відповіді:


10

Ви можете записати час запуску командного рядка та відобразити час запиту. Bash вже відслідковує дату початку кожного командного рядка в його історії, і ви можете відзначити час, коли відображатиметься наступний рядок.

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

Це дає лише друге дозвіл і лише час настінного годинника. Якщо ви хочете кращого дозволу, вам потрібно використовувати зовнішню dateкоманду, яка підтримує %Nформат наносекунд, і DEBUGпастку для виклику, dateперш ніж виконувати команду вчасно.

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

Навіть з DEBUGловушкою, я не думаю, що існує спосіб автоматичного відображення процесорного часу для кожної команди або є більш дискримінаційним, ніж підказки для підказок.


Якщо ви готові використовувати іншу оболонку, ось як отримати звіт про час для кожної команди в zsh (це не узагальнює для інших завдань):

REPORTTIME=0

Ви можете встановити REPORTTIMEбудь-яке ціле значення, інформація про час буде відображатися лише для команд, які використовували більше, ніж ці багато секунд часу процесора.

Zsh взяв цю функцію з csh, де викликається змінна time.


3

Ваші варіанти тут залежатимуть від вашої оболонки. В zshє зручна функція гачка називається , preexec()який запускається прямо перед будь-інтерактивними командами оболонки. Створивши функцію з цим іменем, ви можете спричинити виконання. Ви також можете виконувати функцію, precmd()яка називається, яка запуститься перед тим, як буде зроблено наступний рядок, який буде одразу після завершення вашої команди.

Створюючи цю пару функцій, ви можете мати будь-які довільні команди, які ви хочете виконувати до і після того, як будь-які команди будуть видані під час запиту. Ви можете використовувати це для реєстрації використання оболонки, створення замків, тестування середовища або, як у вашому прикладі, обчислення часу або ресурсів, витрачених під час виконання команди.

У цьому прикладі ми створимо собі часову позначку орієнтиру перед запуском команди, використовуючи preexec()потім обчислимо час, витрачений на виконання команди з використанням precmd()та виведемо її перед запитом, або відімкніть її. Приклад:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

Примітка. Для цього конкретного прикладу є ще простіша вбудована функція. Все, що вам потрібно зробити, це увімкнути звітність про виконання у ZSH, і це зробиться автоматично.

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

У більш практичній реалізації preexec(), я використовую його, щоб побачити, чи працює оболонка всередині tmuxабо screen, якщо це так, щоб надіслати інформацію про поточно запущеній команді вище за течією, яка відображатиметься в імені вкладки.

На жаль, в баші цього маленького механізму не існує. Ось одна спроба людини її повторити . Також дивіться відповідь Гілла на подібний чудовий маленький хак.



Дивіться також unix.stackexchange.com/questions/8607/…
Mikel

Бажаю, щоб це було доступно в баш!
warren

Дивіться посилання Гілла та інших, це реалізовується в башті з невеликим додатковим хитанням. Знову ж таки, чому б вам просто не запустити zsh? Це хижача оболонка з більш вагомими причинами для перемикання, ніж просто це!
Калеб

2
Якщо ви використовуєте zsh, є ще кращий спосіб зробити це. Змінна середовища REPORTTIME, коли встановлено, видаватиме інформацію про час виконання (як якщо б ви виконали команду із 'time' перед нею) для будь-якої команди, що займає більше $ REPORTTIME секунд. Просто встановіть його на 0, і він повинен повідомити вам час для кожної команди, з розбивкою користувача / sys для завантаження.
Джозеф Гарвін

1

Найпростіший спосіб, мабуть, встановити PROMPT_COMMAND. Див. Змінні Bash :

PROMPT_COMMAND
Якщо встановлено, значення інтерпретується як команда для виконання перед друком кожного основного запиту ( $PS1).

Наприклад, щоб не перезаписати будь-яку існуючу команду підказок, ви можете зробити:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

не знав про це - схоже на хороший старт, @cjm
warren

1
Це початок, але не вирішує проблему того, коли знати, коли виконується команда. Сам підказку може бути намальовано хвилин або годин чи днів до введення та запуску команди.
Калеб

0

csh/ tcshмає найкращу підтримку цієї функції (і завжди її мали).

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

Іншими словами, set time=1буде надруковано витрачений час (система, користувач, минуло) будь-якою командою, яка зайняла більше 1 секунди процесорного часу. Звичайний set timeдозволить роздрукувати час для всіх команд.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.