如果设置了分页器,我怎样才能将当前脚本的输出重定向到例如 less?

如果设置了分页器,我怎样才能将当前脚本的输出重定向到例如 less?

我有一组脚本,它们都来自一些共同的背景:

DEFAULT_PAGINATION=''

ownContext=$HOME/.config/exploitation/context.sh
if [ -f "$ownContext" ]; then
  # shellcheck source=$HOME/.config/exploitation/context.sh
  . "$ownContext"
fi

这样任何人都可以覆盖默认配置:一些位置、帮助标志以及在本例中是分页。

例如,为了自动重定向到 less,我尝试过:

# DEFAULT_PAGINATION is the default pagination tool (a program)
# OUTPUT_PAGINATION_FILE acts as an include guard, or contains a filename

if [ -n "$DEFAULT_PAGINATION" ] && [ -z "$OUTPUT_PAGINATION_FILE" ]; then
  paginate() {
    $DEFAULT_PAGINATION "$OUTPUT_PAGINATION_FILE" # paginate tempfile
  }
  trap paginate exit
  OUTPUT_PAGINATION_FILE=$(mktemp)
  export OUTPUT_PAGINATION_FILE
  exec 1<&- # close stdout
  exec 1<>"$OUTPUT_PAGINATION_FILE" # redirect stdout to a temp file
fi

export DEFAULT_PAGINATION=less在另一个上下文文件中进行操作,但不起作用。有什么想法吗?

另外,该解决方案不允许export DEFAULT_PAGINATION="less +F"动态重定向。有解决方案吗?

PS 这个bash标签是故意的

答案1

我不确定是否只通过采购某些东西就可以做到这一点。可以使用自定义解释器(包装器)来完成。

将此示例代码保存为bash-pager

#!/bin/sh

if [ -t 1 ] && [ -n "$PAGER" ]; then
    bash "$@" | sh -c "$PAGER"
else
    exec bash "$@"
fi

使其可执行(chmod +x bash-pager)。然后将您提到的这些脚本的 shebang 更改为

#!/full/path/to/bash-pager

或者(如果bash-pager可以通过$PATH)到达:

#!/usr/bin/env bash-pager

实际上,如果您已经PAGER设置并导出,脚本将会使用它。


我用它是PAGER因为它有点标准。你可能希望你bash-pager看起来更像这样:

#!/bin/sh

ownContext="$HOME/.config/exploitation/context.sh"
if [ -f "$ownContext" ]; then
  . "$ownContext"
fi

DEFAULT_PAGINATION="${DEFAULT_PAGINATION:-$PAGER}"

if [ -t 1 ] && [ -n "$DEFAULT_PAGINATION" ]; then
    bash "$@" | sh -c "$DEFAULT_PAGINATION"
else
    exec bash "$@"
fi

笔记:

  • 如您所见,$DEFAULT_PAGINATION与一起使用sh -c,因此您可以传递带有参数的命令(例如DEFAULT_PAGINATION='cat -n')或管道。
  • [ -t 1 ]检查 stdout 是否为终端。由于采取了这一预防措施,您仍然可以运行one_of_your_scripts | whatever,并且DEFAULT_PAGINATION不会受到干扰。
  • PAGER仍可使用。请参阅这个问题
  • 我不知道context.sh该做什么。有几个问题:

    • context.sh可能会在解释器的上下文中做一些你不想要的事情,因此bash-pager可能不希望将其引入。
    • context.sh可能会在脚本中执行您明确想要执行的操作,因此无论如何您都希望在每个脚本中都提供它。
    • context.sh可能需要bash。注意bash-pager被设计为包装在 之上,bash但它的解释器 (shebang) 是/bin/sh。不过更改为bash很简单。
    • context.sh可能会用来set改变$@。如果确实如此,那么"$@"以后bash-pager可能不会扩展到我们需要的范围。

    这是需要您解决的。请注意,解释器只需要DEFAULT_PAGINATION/ PAGER。您可以告诉用户在他们的文件中设置并导出其中一个profile(如果他们想要该功能)。然后就bash-pager不需要提供任何内容了。

答案2

假设您想要script1.sh使用 进行分页less

您可以创建一个包装器脚本,进行如下分页script1.sh

#!/usr/bin/env bash

/path/to/script1.sh | less

当您运行包装器脚本时,它将运行script1.sh并使用对其进行分页less

为什么这对您不起作用?有什么原因吗?

相关内容