mem*_*ecs 147 bash terminal stdout
Bash命令的输出是否存储在任何寄存器中?例如类似于$?捕获输出而不是退出状态.
我可以将输出分配给变量:
output=$(command)
Run Code Online (Sandbox Code Playgroud)
但这更像打字......
lin*_*ing 154
您可以使用: $(!!)
重新计算(不重复使用)最后一个命令的输出.
在!!自身执行的最后一个命令.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
Run Code Online (Sandbox Code Playgroud)
kon*_*box 80
答案是不.Bash不会将任何输出分配给任何参数或其内存中的任何块.此外,您只能通过其允许的接口操作访问Bash.除非你破解它,否则无法访问Bash的私有数据.
Con*_*nor 38
一个我用了很多年的。
.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; }
Run Code Online (Sandbox Code Playgroud)
$ find . -name 'filename' | cap
/path/to/filename
$ ret
/path/to/filename
Run Code Online (Sandbox Code Playgroud)
我倾向于添加| cap到我所有命令的末尾。这样,当我发现我想对运行缓慢的命令的输出进行文本处理时,我总是可以使用ret.
anu*_*ava 11
一种方法是使用trap DEBUG:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Run Code Online (Sandbox Code Playgroud)
现在最近执行的命令的stdout和stderr将可用 /tmp/out.log
唯一的缺点是它会执行两次命令:一次将输出和错误重定向到/tmp/out.log正常情况.可能还有一些方法可以防止这种行为.
如果您使用的是Mac,并且不介意将输出存储在剪贴板中而不是写入变量,则可以使用pbcopy和pbpaste作为解决方法。
例如,不要这样做来查找文件并将其内容与另一个文件进行比较:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Run Code Online (Sandbox Code Playgroud)
您可以这样做:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
Run Code Online (Sandbox Code Playgroud)
/var/bar/app/one.php运行第一个命令时,字符串在剪贴板中。
顺便说一句,pb进入pbcopy并pbpaste代表粘贴板(剪贴板的同义词)。
受到 anubhava 的回答的启发,我认为这实际上是不可接受的,因为它每个命令运行两次。
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
Run Code Online (Sandbox Code Playgroud)
这样,最后一个命令的输出在 /tmp/last 中,并且该命令不会被调用两次。
是啊,为什么每次都要输入额外的行?同意。您可以将命令返回的结果重定向到管道输入,但是将打印输出重定向到输入(1>&0)是不行的,至少对于多行输出来说不行。此外,您也不想在每个文件中一次又一次地编写相同的函数。那么让我们尝试一些其他的东西。
printf -v myoutput "`cmd`"
Run Code Online (Sandbox Code Playgroud)
例如
printf -v var "`echo ok;
echo fine;
echo thankyou`"
echo "$var" # don't forget the backquotes and quotes in either command.
Run Code Online (Sandbox Code Playgroud)
如果您不将文件导出到任何地方并且打算仅在本地使用它,则可以让终端设置函数声明。您必须在~/.bashrc文件或~/.profile文件中添加该功能。在第二种情况下,您需要启用Run command as login shellfrom Edit>Preferences>yourProfile>Command。
做一个简单的函数,说:
get_prev() # preferably pass the commands in quotes. Single commands might still work without.
{
# 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
# option 3: (I actually used below)
eval "$*" > /tmp/out # or simply "$*" > /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 Code Online (Sandbox Code Playgroud)
因此,我们在选项 1 中所做的是将整个命令打印到临时文件中/tmp/exe并运行它,并将输出保存到另一个文件中/tmp/out,然后将/tmp/out文件的内容逐行读取到数组中。选项 2 和选项 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'"
Run Code Online (Sandbox Code Playgroud)
现在,bash 即使在先前的作用域之外也会保存变量,因此即使在主脚本中的函数之外也可以访问在函数中arr创建的变量:get_prev
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++))
do
echo ${arr[i]}
done
Run Code Online (Sandbox Code Playgroud)
#if you're sure that your output won't have escape sequences you bother about, you may simply print the array
printf "${arr[*]}\n"
Run Code Online (Sandbox Code Playgroud)
#if you're sure that your output won't have escape sequences you bother about, you may simply print the array
printf "${arr[*]}\n"
Run Code Online (Sandbox Code Playgroud)
我一直在使用它来打印多个/管道/两个命令的空格分隔输出,以行分隔:
get_prev()
{
usage()
{
echo "Usage: alphabet [ -h | --help ]
[ -s | --sep SEP ]
[ -v | --var VAR ] \"command\""
}
ARGS=$(getopt -a -n alphabet -o hs:v: --long help,sep:,var: -- "$@")
if [ $? -ne 0 ]; then usage; return 2; fi
eval set -- $ARGS
local var="arr"
IFS=$(echo -en '\n\b')
for arg in $*
do
case $arg in
-h|--help)
usage
echo " -h, --help : opens this help"
echo " -s, --sep : specify the separator, newline by default"
echo " -v, --var : variable name to put result into, arr by default"
echo " command : command to execute. Enclose in quotes if multiple lines or pipelines are used."
shift
return 0
;;
-s|--sep)
shift
IFS=$(echo -en $1)
shift
;;
-v|--var)
shift
var=$1
shift
;;
-|--)
shift
;;
*)
cmd=$option
;;
esac
done
if [ ${#} -eq 0 ]; then usage; return 1; fi
ERROR=$( { eval "$*" > /tmp/out; } 2>&1 )
if [ $ERROR ]; then echo $ERROR; return 1; fi
local a=()
exec 3</tmp/out
while read -u 3 -r line
do
a+=($line)
done
exec 3<&-
eval $var=\(\${a[@]}\)
print_arr $var # comment this to suppress output
}
print()
{
eval echo \${$1[@]}
}
print_arr()
{
eval printf "%s\\\n" "\${$1[@]}"
}
Run Code Online (Sandbox Code Playgroud)
例如:
get_prev -s " " -v myarr "cmd1 | cmd2; cmd3 | cmd4"
Run Code Online (Sandbox Code Playgroud)
现在tr命令在其他地方也很有用,例如
get_prev -s ' ' -v myarr whereis python # or "whereis python"
# can also be achieved (in this case) by
whereis python | tr ' ' '\n'
Run Code Online (Sandbox Code Playgroud)
但对于多个/管道命令......你现在知道了。:)
-希曼舒
| 归档时间: |
|
| 查看次数: |
112148 次 |
| 最近记录: |