Вы можете уберечь себя от набора текста $(your_cmd)с помощью обратных галочек: `your_cmd`согласно руководству Gnu Bash они функционально идентичны. Конечно, это также зависит от предупреждения @memecs
На практике вывод команд является детерминированным, поэтому я не буду мучиться из-за повторного вычисления. Это, безусловно, полезно, когда вы хотите сделать что-то вроде того, git diff $(!!)где предыдущая команда была findвызовом.
@ user2065875, хотя обратные пометки все еще работают в Bash, они устарели в пользу $().
Курчинский
87
Ответ - нет. Bash не выделяет никакого вывода ни одному параметру или любому блоку в своей памяти. Кроме того, вам разрешен доступ к Bash только с помощью разрешенных операций интерфейса. Личные данные Bash не доступны, если вы не взломаете их.
Возможно ли иметь какую-то пользовательскую функцию промежуточного программного обеспечения bash, которая запускается перед каждой командой, где все, что она делает, это сохраняет полученный результат во что-то, что действует как внутренний буфер обмена (скажем, BASH_CLIPBOARD)?
Пэт Нидхэм
@PatNeedham Не уверен. Проверьте загружаемые модули. Посмотри, сможешь ли ты написать один.
konsolebox
12
Один из способов сделать это с помощью trap DEBUG:
Теперь stdout и stderr последней выполненной команды будут доступны в /tmp/out.log
Единственным недостатком является то, что он будет выполнять команду дважды: один раз для перенаправления вывода и ошибок /tmp/out.logи один раз в обычном режиме. Возможно, есть какой-то способ предотвратить такое поведение.
поэтому, когда я набираю rm -rf * && cd .., не только текущий каталог, но и родительский каталог будет удален ?? этот подход кажется мне очень опасным
phil294
1
Теперь, как мне отменить это действие?
Картик Чаухан
5
@KartikChauhan: Просто сделайtrap '' DEBUG
анубхава
7
Если вы работаете на Mac и не против сохранить результаты в буфере обмена вместо записи в переменную, вы можете использовать pbcopy и pbpaste в качестве обходного пути.
Например, вместо того, чтобы сделать это, чтобы найти файл и сравнить его содержимое с другим файлом:
на Linux $ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
Си-Мики
Интересно, я никогда не думал об использовании pbpasteвместе с подстановкой команд.
Шридхар Сарнобат
Что, если я сделаю первый и позже пойму, что это было неэффективно, как мне сэкономить вычислительное время без повторного запуска со вторым вариантом?
НельсонГон
4
Вдохновленный ответом анубхавы, который, я думаю, на самом деле неприемлем, поскольку он запускает каждую команду дважды.
Один недостаток, который я обнаружил, заключается в том, что ни одна из ваших команд не думает, что они больше работают в tty, а это значит, что вам нужно особое внимание, чтобы коды цвета работали для таких утилит, как grepили git diff+1, в любом случае
Марти Нил
2
Как сказал konsolebox, вам придется взломать сам bash. Вот довольно хороший пример того, как можно этого достичь. Репозиторий stderred (на самом деле предназначен для окраски стандартного вывода) дает инструкции о том, как его построить.
Я дал ему попробовать: определение некоторого нового файлового дескриптора внутри, .bashrcкак
exec 41>/tmp/my_console_log
(число произвольно) и измените его stderred.cсоответствующим образом, чтобы содержимое также записывалось на fd 41. Это вроде работает, но содержит множество байтов NUL, странное форматирование и в основном представляет собой двоичные данные, которые не читаются. Может быть, кто-то с хорошим пониманием C мог бы попробовать это.
Если это так, все, что нужно для получения последней напечатанной строки tail -n 1 [logfile].
Да, почему каждый раз соглашались набирать лишние строки. Вы можете перенаправить возвращенный на вход, но выход на вход (1> & 0) - нет. Также вы не захотите писать функцию снова и снова в каждом файле для одного и того же.
Если вы нигде не экспортируете файлы и намереваетесь использовать их только локально, вы можете настроить Терминал на объявление функции. Вы должны добавить функцию в ~/.bashrcфайл или в ~/.profileфайл. Во втором случае вам нужно включить Run command as login shellс Edit>Preferences>yourProfile>Command.
Сделайте простую функцию, скажем:
get_prev(){# option 1: create an executable with the command(s) and run it
echo $*>/tmp/exe
bash /tmp/exe >/tmp/out
# option 2: if your command is single command (no-pipe, no semi-colons), still it may not run correct in some exceptions#echo `$*` > /tmp/out# return the command(s) outputs line by line
IFS=$(echo -en "\n\b")
arr=()
exec 3</tmp/out
while read -u 3-r line
do
arr+=($line)
echo $line
done
exec 3<&-}
# capture the output of a command so it can be retrieved with ret
cap (){ tee /tmp/capture.out}# return the output of the most recent command that was captured by cap
ret (){ cat /tmp/capture.out }
использование
$ find .-name 'filename'| cap
/path/to/filename
$ ret
/path/to/filename
Я склонен добавлять | capв конец всех моих команд. Таким образом, когда я нахожу, что хочу выполнить обработку текста на выходе медленной команды, я всегда могу получить ее res.
Что такое точка cat -в cap () { cat - | tee /tmp/capture.out}здесь? Есть ли cap () { tee /tmp/capture.out }брать на себя какую - либо икоту я пропускаю?
Уотсон
1
@ Уотсон, хорошая мысль! Я не знаю, почему у меня это там, вероятно, привычка. Должен ли я добавить cat - | cat - | cat -заранее, чтобы сделать его более интересным? Fix Я исправлю это, как только протестирую, чтобы убедиться, что это действительно спандрел
Коннор
0
Не уверен, что именно вам это нужно, поэтому этот ответ может быть неактуальным. Вы всегда можете сохранить выходные данные команды:, netstat >> output.txtно я не думаю, что это то, что вы ищете.
Хотя, конечно, есть варианты программирования; вы могли бы просто заставить программу прочитать приведенный выше текстовый файл после выполнения этой команды и связать ее с переменной, а в Ruby, моем предпочтительном языке, вы можете создать переменную из вывода команды, используя 'backticks':
output =`ls`#(this is a comment) create variable out of commandif output.include?"Downloads"#if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."else
print "there is no directory called downloads in this file."
end
Вставьте это в файл .rb и запустите его: ruby file.rbи он создаст переменную из команды и позволит вам манипулировать ею.
«Не знаю точно, для чего вам это нужно» Ну, скажем, вы (под этим я имею в виду меня ) просто запустили сценарий большой продолжительности, хотите найти выходные данные и тупо забыли перенаправить выходные данные перед выполнением. Теперь я хочу попытаться исправить мою глупость без повторного запуска сценария.
ОАО
0
У меня есть идея, что у меня нет времени, чтобы попытаться реализовать немедленно.
Но что, если вы сделаете что-то вроде следующего:
$ MY_HISTORY_FILE =`get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1| tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!
Могут быть проблемы с буферизацией ввода-вывода. Также файл может стать слишком большим. Нужно было бы найти решение этих проблем.
Если вы не хотите пересчитывать предыдущую команду, вы можете создать макрос, который сканирует текущий буфер терминала, пытается угадать вывод -suppposed- последней команды, копирует его в буфер обмена и, наконец, вводит его в терминал.
Его можно использовать для простых команд, которые возвращают одну строку вывода (протестировано в Ubuntu 18.04 с gnome-terminal).
Установите следующие инструменты: xdootool, xclip,ruby
В gnome-terminalиди Preferences -> Shortcuts -> Select allи установите его Ctrl+shift+a.
Создайте следующий скрипт ruby:
cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while {|item| item ==""}
g = f.drop_while {|item| item.start_with?"${USER}@"}
h = g[0]
print h
EOF
В настройках клавиатуры добавьте следующее сочетание клавиш:
Ответы:
Вы можете использовать
$(!!)
для пересчета (не повторного использования) вывод последней команды.Сам
!!
по себе выполняет последнюю команду.источник
$(your_cmd)
с помощью обратных галочек:`your_cmd`
согласно руководству Gnu Bash они функционально идентичны. Конечно, это также зависит от предупреждения @memecsgit diff $(!!)
где предыдущая команда былаfind
вызовом.$()
вместо обратной галочки. Но, наверное, нечего терять сон. github.com/koalaman/shellcheck/wiki/SC2006$()
.Ответ - нет. Bash не выделяет никакого вывода ни одному параметру или любому блоку в своей памяти. Кроме того, вам разрешен доступ к Bash только с помощью разрешенных операций интерфейса. Личные данные Bash не доступны, если вы не взломаете их.
источник
Один из способов сделать это с помощью
trap DEBUG
:Теперь stdout и stderr последней выполненной команды будут доступны в
/tmp/out.log
Единственным недостатком является то, что он будет выполнять команду дважды: один раз для перенаправления вывода и ошибок
/tmp/out.log
и один раз в обычном режиме. Возможно, есть какой-то способ предотвратить такое поведение.источник
rm -rf * && cd ..
, не только текущий каталог, но и родительский каталог будет удален ?? этот подход кажется мне очень опаснымtrap '' DEBUG
Если вы работаете на Mac и не против сохранить результаты в буфере обмена вместо записи в переменную, вы можете использовать pbcopy и pbpaste в качестве обходного пути.
Например, вместо того, чтобы сделать это, чтобы найти файл и сравнить его содержимое с другим файлом:
Вы могли бы сделать это:
Строка
/var/bar/app/one.php
находится в буфере обмена при запуске первой команды.Кстати, pb in
pbcopy
иpbpaste
расшифровывается как pasteboard, синоним буфера обмена.источник
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
вместе с подстановкой команд.Вдохновленный ответом анубхавы, который, я думаю, на самом деле неприемлем, поскольку он запускает каждую команду дважды.
Таким образом, выходные данные последней команды находятся в / tmp / last, и команда не вызывается дважды.
источник
grep
илиgit diff
+1, в любом случаеКак сказал konsolebox, вам придется взломать сам bash. Вот довольно хороший пример того, как можно этого достичь. Репозиторий stderred (на самом деле предназначен для окраски стандартного вывода) дает инструкции о том, как его построить.
Я дал ему попробовать: определение некоторого нового файлового дескриптора внутри,
.bashrc
как(число произвольно) и измените его
stderred.c
соответствующим образом, чтобы содержимое также записывалось на fd 41. Это вроде работает, но содержит множество байтов NUL, странное форматирование и в основном представляет собой двоичные данные, которые не читаются. Может быть, кто-то с хорошим пониманием C мог бы попробовать это.Если это так, все, что нужно для получения последней напечатанной строки
tail -n 1 [logfile]
.источник
Да, почему каждый раз соглашались набирать лишние строки. Вы можете перенаправить возвращенный на вход, но выход на вход (1> & 0) - нет. Также вы не захотите писать функцию снова и снова в каждом файле для одного и того же.
Если вы нигде не экспортируете файлы и намереваетесь использовать их только локально, вы можете настроить Терминал на объявление функции. Вы должны добавить функцию в
~/.bashrc
файл или в~/.profile
файл. Во втором случае вам нужно включитьRun command as login shell
сEdit>Preferences>yourProfile>Command
.Сделайте простую функцию, скажем:
В основном скрипте:
Bash сохраняет переменную даже за пределами предыдущей области видимости:
источник
Очень простое решение
Тот, который я использовал в течение многих лет.
Скрипт (добавить в свой
.bashrc
или.bash_profile
)использование
Я склонен добавлять
| cap
в конец всех моих команд. Таким образом, когда я нахожу, что хочу выполнить обработку текста на выходе медленной команды, я всегда могу получить ееres
.источник
cat -
вcap () { cat - | tee /tmp/capture.out}
здесь? Есть лиcap () { tee /tmp/capture.out }
брать на себя какую - либо икоту я пропускаю?cat - | cat - | cat -
заранее, чтобы сделать его более интересным? Fix Я исправлю это, как только протестирую, чтобы убедиться, что это действительно спандрелНе уверен, что именно вам это нужно, поэтому этот ответ может быть неактуальным. Вы всегда можете сохранить выходные данные команды:,
netstat >> output.txt
но я не думаю, что это то, что вы ищете.Хотя, конечно, есть варианты программирования; вы могли бы просто заставить программу прочитать приведенный выше текстовый файл после выполнения этой команды и связать ее с переменной, а в Ruby, моем предпочтительном языке, вы можете создать переменную из вывода команды, используя 'backticks':
Вставьте это в файл .rb и запустите его:
ruby file.rb
и он создаст переменную из команды и позволит вам манипулировать ею.источник
У меня есть идея, что у меня нет времени, чтобы попытаться реализовать немедленно.
Но что, если вы сделаете что-то вроде следующего:
Могут быть проблемы с буферизацией ввода-вывода. Также файл может стать слишком большим. Нужно было бы найти решение этих проблем.
источник
Я думаю, что использование команды сценария может помочь. Что-то вроде,
скрипт -c bash -qf fifo_pid
Использование функций bash для установки после разбора.
источник
Если вы не хотите пересчитывать предыдущую команду, вы можете создать макрос, который сканирует текущий буфер терминала, пытается угадать вывод -suppposed- последней команды, копирует его в буфер обмена и, наконец, вводит его в терминал.
Его можно использовать для простых команд, которые возвращают одну строку вывода (протестировано в Ubuntu 18.04 с
gnome-terminal
).Установите следующие инструменты:
xdootool
,xclip
,ruby
В
gnome-terminal
идиPreferences -> Shortcuts -> Select all
и установите егоCtrl+shift+a
.Создайте следующий скрипт ruby:
В настройках клавиатуры добавьте следующее сочетание клавиш:
bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '
Вышеуказанный ярлык:
источник