根据长度将命令的输出输入less或into cat

Gyo*_*yom 6 shell zsh pager

首先,让我说这是一个编程问题(因此不属于超级用户)因为我在谈论shell编程.这可能几乎是一个高尔夫问题,但我没有答案开始,所以任何帮助将不胜感激:-)

所以,故事是:我喜欢less--quit-if-one-screen选项来管理它,因为它很舒服:less在不必要时不会妨碍我.或者是吗?当我的提示已经在终端窗口的底部时,此选项完全符合我的要求(即less行为cat).但是,当我当前的提示位于窗口顶部时,less首先打印大量空行以清除屏幕,然后在屏幕底部打印出我的(短)文件,然后它才会意识到文本较少比一个屏幕,所以它退出,我得到我的提示.

但是这种行为并不是很好,因为所有那些无用的空白行.我尝试了不同的选项,或编写脚本和别名,我能想到的最好的就是这个(我使用的是zsh,所以shell已经能够复制管道等等):

function catless() {
 cat   \
  >>( bucket -$LINES | cat  ) \
  >>( bucket +$LINES | less )
}
Run Code Online (Sandbox Code Playgroud)

bucket我刚写的另一个脚本在哪里,如果它小于N行(带-N)或多于N(带+ N),则将stdin复制到stdout.我在这里发布了它:http://snipt.net/Gyom/copy-stdin-to-stdout-or-not-depending-on-length

ls | catless几乎工程.但是,出于同步原因,这里涉及的不同进程无法正确访问终端,并且所有内容都在后台执行(特别是,我从来没有less在这里得到正确的,并且提示很快就会回来).但也许我走错了路.

因此,总而言之,我想要的是这样一个函数/脚本/我可以输入的任何内容,ls | catless它的行为与输出短于一个屏幕时的行为完全相同,就像更长时间一样.ls | catlsls | less

有任何想法吗 ?

Emi*_*Sit 5

-X标志可以帮助你(从以下(1)):

  -X or --no-init
         Disables sending the termcap initialization and deinitialization
         strings to the terminal.   This  is  sometimes desirable if the
         deinitialization string does something unnecessary, like
         clearing the screen.
Run Code Online (Sandbox Code Playgroud)

所以,以下应该做你想要的:

export LESS="-E -X"
Run Code Online (Sandbox Code Playgroud)

或者,既然你喜欢-quit-if-one-screen,你可以改为:

export LESS="-F -X"
Run Code Online (Sandbox Code Playgroud)


Chr*_*sen 1

在较少版本 406 的新闻中,我看到 \xe2\x80\x9cDon\t 无法移动到第一页屏幕的底部。\xe2\x80\x9d。你有哪个版本?我的系统版本是382,打印前它会移动到屏幕底部(如果只有一屏并-F使用,会导致空行)。

\n\n

我刚刚安装了版本 436,它似乎可以在给定时执行您想要的操作-FX(将其与您的其他首选项一起放入LESS环境变量中,以便让任何内容通过运行来使用这些首选项less)。

\n\n

如果您无法获取新版本,您可以尝试以下方法:

\n\n
function catless() {\n    local line buffer=\'\' num=0 limit=$LINES\n    while IFS=\'\' read -r line; do\n        buffer="$buffer$line"$\'\\n\'\n        line=\'\'\n        num=$(( num+1 ))\n        [[ $num -ge $limit ]] && break\n    done\n    if [[ $num -ge $limit ]]; then \n        { printf %s "$buffer$line"; cat } | less\n    else\n        printf %s "$buffer$line"\n    fi\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

关键是 shell 必须在(可能)启动之前知道文件中的行数是否多于屏幕less(您最初使用的多 io 技术只能在后台运行)。如果是内壳read对您来说不够强大,您可以通过稍微修改代码来替换它:

\n\n
function cat_up_to_N_lines_and_exit_success_if_more() {\n    # replace this with some other implmentation\n    # if read -r is not robust enough\n    local line buffer=\'\' num=0 limit="$1"\n    while IFS=\'\' read -r line; do\n        buffer="$buffer$line"$\'\\n\'\n        line=\'\'\n        num=$(( num+1 ))\n        [[ $num -ge $limit ]] && break\n    done\n    printf %s "$buffer$line"\n    [[ $num -ge $limit ]]\n}\nfunction catless() {\n    local limit=$LINES buffer=\'\'\n    # capture first $limit lines\n    # the \\0 business is to guard the trailing newline\n    buffer=${"$(\n    cat_up_to_N_lines_and_exit_success_if_more $limit\n    ec=$?\n    printf \'\\0\'\n    exit $ec)"%$\'\\0\'}\n    use_pager=$?\n    if [[ $use_pager -eq 0 ]]; then\n        { printf \'%s\' "$buffer"; cat } | less\n    else\n        printf \'%s\' "$buffer"\n    fi\n}\n
Run Code Online (Sandbox Code Playgroud)\n