Сохраняется ли вывод команды Bash в каком-либо регистре? Например, что-то похожее на $?
захват вывода вместо состояния выхода.
Я мог бы назначить вывод переменной:
output=$(command)
но это больше печатать ...
Сохраняется ли вывод команды Bash в каком-либо регистре? Например, что-то похожее на $?
захват вывода вместо состояния выхода.
Я мог бы назначить вывод переменной:
output=$(command)
но это больше печатать ...
Ответы:
Вы можете использовать $(!!)
для пересчета (не повторного использования) вывод последней команды.
Сам !!
по себе выполняет последнюю команду.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
$(your_cmd)
с помощью обратных галочек: `your_cmd`
согласно руководству Gnu Bash они функционально идентичны. Конечно, это также зависит от предупреждения @memecs
git diff $(!!)
где предыдущая команда была find
вызовом.
$()
вместо обратной галочки. Но, наверное, нечего терять сон. github.com/koalaman/shellcheck/wiki/SC2006
$()
.
Ответ - нет. Bash не выделяет никакого вывода ни одному параметру или любому блоку в своей памяти. Кроме того, вам разрешен доступ к Bash только с помощью разрешенных операций интерфейса. Личные данные Bash не доступны, если вы не взломаете их.
Один из способов сделать это с помощью trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Теперь stdout и stderr последней выполненной команды будут доступны в /tmp/out.log
Единственным недостатком является то, что он будет выполнять команду дважды: один раз для перенаправления вывода и ошибок /tmp/out.log
и один раз в обычном режиме. Возможно, есть какой-то способ предотвратить такое поведение.
rm -rf * && cd ..
, не только текущий каталог, но и родительский каталог будет удален ?? этот подход кажется мне очень опасным
trap '' DEBUG
Если вы работаете на Mac и не против сохранить результаты в буфере обмена вместо записи в переменную, вы можете использовать pbcopy и pbpaste в качестве обходного пути.
Например, вместо того, чтобы сделать это, чтобы найти файл и сравнить его содержимое с другим файлом:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Вы могли бы сделать это:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
Строка /var/bar/app/one.php
находится в буфере обмена при запуске первой команды.
Кстати, pb in pbcopy
и pbpaste
расшифровывается как pasteboard, синоним буфера обмена.
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
вместе с подстановкой команд.
Вдохновленный ответом анубхавы, который, я думаю, на самом деле неприемлем, поскольку он запускает каждую команду дважды.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
Таким образом, выходные данные последней команды находятся в / tmp / last, и команда не вызывается дважды.
grep
или git diff
+1, в любом случае
Как сказал 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<&-
}
В основном скрипте:
#run your command:
cmd="echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
get_prev $cmd
#or simply
get_prev "echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
Bash сохраняет переменную даже за пределами предыдущей области видимости:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done
Тот, который я использовал в течение многих лет.
.bashrc
или .bash_profile
)# 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 }
брать на себя какую - либо икоту я пропускаю?
cat - | cat - | cat -
заранее, чтобы сделать его более интересным? Fix Я исправлю это, как только протестирую, чтобы убедиться, что это действительно спандрел
Не уверен, что именно вам это нужно, поэтому этот ответ может быть неактуальным. Вы всегда можете сохранить выходные данные команды:, netstat >> output.txt
но я не думаю, что это то, что вы ищете.
Хотя, конечно, есть варианты программирования; вы могли бы просто заставить программу прочитать приведенный выше текстовый файл после выполнения этой команды и связать ее с переменной, а в Ruby, моем предпочтительном языке, вы можете создать переменную из вывода команды, используя 'backticks':
output = `ls` #(this is a comment) create variable out of command
if 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
и он создаст переменную из команды и позволит вам манипулировать ею.
У меня есть идея, что у меня нет времени, чтобы попытаться реализовать немедленно.
Но что, если вы сделаете что-то вроде следующего:
$ 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
В настройках клавиатуры добавьте следующее сочетание клавиш:
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 '
Вышеуказанный ярлык: