ls $DIRNAME
我希望脚本可以运行命令并显示以下内容
ls /full/path/to/some/dir
目的是保存所有调用的shell命令及其参数的日志。也许有更好的方法来生成这样的日志吗?
setopt VERBOSE
作为调试工具,
setopt XTRACE
eval
和Soth的exe
函数来同时显示并运行该命令。这对于一些带管道的命令非常有用,否则它们只会显示部分的命令内容或者根本都不会显示。
没有使用eval的情况下:
exe() { echo "\$ $@" ; "$@" ; }
exe ls -F | grep *.txt
输出:
$
file.txt
使用 eval:
exe() { echo "\$ $@" ; "$@" ; }
exe eval 'ls -F | grep *.txt'
哪些输出
$ exe eval 'ls -F | grep *.txt'
file.txt
set verbose
或set echo
(甚至可以同时设置两者,但大多数情况下可能会导致一些重复)。
verbose
选项打印几乎完全与您键入的shell表达式相同。
echo
选项更能指示通过生成将要执行的内容。
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#verbose
http://www.tcsh.org/tcsh.html/Special_shell_variables.html#echo
特殊的shell变量
verbose
如果设置了,会导致每个命令的单词在历史替换后被打印出来。由-v命令行选项设置。
echo
如果设置了,每个带有参数的命令在执行之前都会被回显。对于非内置命令,所有扩展都会在回显之前发生。内置命令在命令和文件名替换之前被回显,因为这些替换是有选择性的。由-x命令行选项设置。
根据Soth的回答。
可以创建一个没有高亮(未指定语言)的Markdown输出。
set -x
exe() { echo "\`\$\$ ${@/eval/} \`" ; "$@" ; }
set -x
exe() { echo "\`\$\$ ${@/eval/} \`" ; "$@" ; }
echo
echo -----------------------------------------------------------
echo # Setup
echo Lets take a random keyframe from in.mp4:
echo
exe eval "kfn=20"
echo
echo "kf=\$(ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | grep 'frame,video,0,1' | head -$kfn | tail -1 | perl -pe 's|frame,video,0,1,.*?,(.*?),.*|\1|') "
exe eval "kf=$(ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | grep 'frame,video,0,1' | head -$kfn | tail -1 | perl -pe 's|frame,video,0,1,.*?,(.*?),.*|\1|') "
echo
echo Lets select keyframe at $kf. Here are the timestamps of the all the frames from in.mp4 around this keyframe.
echo
exe eval "ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | perl -pe 's|frame,video,0,(.*?),.*?,(.*?),.*|\2 \1|' | perl -pe 's|(.*?) 1|\1\tKF|' | perl -pe 's|(.*?) 0|\1|' |grep -A 5 -B 5 --color $kf"
echo
echo Lets compare 2 methods of split: actual losslesscut 3.53.0 and another one
echo
让我们从in.mp4文件中随意选取一个关键帧:
$$ kfn=20
kf=$(ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | grep 'frame,video,0,1' | head -20 | tail -1 | perl -pe 's|frame,video,0,1,.?,(.?),.*|\1|')
$$ kf=3.803792
让我们选择位于3.803792的关键帧。以下是in.mp4文件中此关键帧周围所有帧的时间戳。
$$ ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | perl -pe 's|frame,video,0,(.*?),.*?,(.*?),.*|\2 \1|' | perl -pe 's|(.*?) 1|\1\tKF|' | perl -pe 's|(.*?) 0|\1|' |grep -A 5 -B 5 --color 3.803792
3.720375
3.737083
3.753750
3.770417
3.787125
**3.803792** KF
3.820500
3.837167
3.853833
3.870542
3.887208
如果你只想记录特定的命令,而不是每一行,set -x
使用起来有些困难。但你可以使用这个函数打印任何命令,并在前面加上 $
:
function run() {
echo -n '$' # Print $ without a newline.
for arg in "$@"; do
printf " %q" "$arg" # Print $arg, properly escaped.
done
echo # Print a newline.
"$@"
}
使用方法:
run ls /full/path/to/some/dir
%q
格式说明符的printf
,可以确保输出以适合复制和粘贴到shell中的方式打印,即使存在空格或其他特殊字符。它似乎使用\
转义空格而不是添加引号,但输出确实正确地表示了实际运行的内容。#!/bin/bash
cmd="ls $PWD"
echo $cmd; eval $cmd
cmd="cat $PWD/whatfille.txt"
echo "-> $cmd"; eval $cmd #this prefixes to command for better reading