【问题标题】:Increment the title of files output by a command in a shell script增加 shell 脚本中命令输出的文件标题
【发布时间】:2021-10-05 07:17:52
【问题描述】:

我制作了这个简单的 bash 脚本来截取全屏截图并将其保存到图片文件夹中

#!/usr/bin/bash

xfce4-screenshooter -f -s /home/rgcodes/Pictures/Screenshot_$scrshotcount.png 
let "scrshotcount++"

...遇到了问题。 scrshotcount 是我在/etc/environment 中定义的全局变量,每次脚本运行时都会递增。但是,脚本无法全局递增变量,并导致脚本仅覆盖之前的屏幕截图。在 Google 和 Stack Overflow 上的搜索显示,这个问题根本不简单(关于子 shell 无法为父代更改变量的问题),找到其他方法会更好。

这是我的问题。我们如何将数字(按升序)附加到脚本抛出的屏幕截图,以便它们像在 Windows 上拍摄的那样保存?(Windows 自动为匹配文件名添加后缀,而不是覆盖它们,因此所有屏幕截图都具有相同的名称 '截图'和截图命令被使用的次数。)

我现在使用@erikMD 的方法作为临时权宜之计。

【问题讨论】:

  • 您可以通过将日期时间附加到输出屏幕 .png 文件名来大大简化事情:xfce4-screenshooter -f -s /home/rgcodes/Pictures/Screenshot_$(date +"%Y_%m_%d_%I_%M_%S_%p").png
  • 如果您真的想将计数附加到屏幕截图名称中,那么您可以执行xfce4-screenshooter -f -s /home/rgcodes/Pictures/Screenshot_$(awk '{print $1}' <(wc -l <(ls /home/grcodes/Pictures/Screenshot*.png))).png 之类的操作。此命令计算名为“Screenshot*.png”(星号是通配符)的文件的数量,并在新的屏幕截图图像文件名中使用该数量。需要注意的是,如果没有截图,那么第一个截图将被命名为“Screenshot_0.png”
  • 如果旧的屏幕截图被删除,计数器方法会覆盖较新的屏幕截图。

标签: linux bash linux-mint xfce


【解决方案1】:

除了使用日期而不是计数器的出色建议之外,还有一种使用计数器的方法:/

dir=$HOME/Pictures

# find the current maximum value
current_max=$( 
    find "$dir" -name Screenshot_\*.png -print0 \
    | sort -z -V \
    | tail -z -n 1
)
if [[ ! $current_max =~ _([0-9]+)\.png ]]; then
    echo "can't find the screenshot with the maximum counter value" >&2
    exit 1
fi

# increment it
counter=$(( 1 + ${BASH_REMATCH[1]} ))

# and use it
xfce4-screenshooter -f -s "$dir/Screenshot_${counter}.png"

您必须手动创建Screenshot_1.png 文件。

【讨论】:

  • 它似乎不起作用。即使我在指定目录中有Screenshot_1,终端也会返回“找不到最大计数器值”。 @j_b 方法似乎也不起作用,它们可能是由相同的原因引起的吗?我的shebang是#!/usr/bin/bash btw
  • 哦,我的 find 命令弄错了:find "$dir" -name Screenshot_\*.png -print0
  • 返回/usr/bin/scrshot2: line 10: warning: command substitution: ignored null byte in input can't find the screenshot with the maximum counter value 我还修正了第一行的拼写错误,还是不开心。
  • bash -x 运行它并显示输出
  • 我创建了一个新的子文件夹,它现在可以工作了。请更正第一行中的拼写错误,非常感谢您的帮助!
【解决方案2】:

确实,正如 @j_b 在 cmets 中所建议的,您绝对应该尝试使用带有命令 date +"$format" 的时间戳。

FTR,同样的思路在this project of a gnome-screenshot bash wrapper中实现here
(免责声明:我是这个 repo 的作者)。

示例命令:

date "+%Y-%m-%d_%H-%M-%S"

↓

2021-07-29_19-13-30

所以整个脚本可能是这样的:

#!/usr/bin/env bash

xfce4-screenshooter -f -s "$HOME/Pictures/Screenshot_$(date "+%Y-%m-%d_%H-%M-%S").png"

(请注意,我添加了缺少的双引号,并修改了您的shebang,因为/usr/bin/env bash/bin/bash/usr/bin/bash 更便携。)

【讨论】:

  • 您的解决方案有效,但不是我想要的。
【解决方案3】:

下面的@rgcodes 是一个脚本,它将根据您的原始帖子捕获带有数字计数指示符的屏幕截图。 (在 Ubuntu 20.04 上测试过)

脚本内容:

#!/bin/bash

set -uo pipefail

# add source file and line number to xtrace output 
# i.e. when running:  bash -x ./your_script_name.sh
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

capture_screenshot() {
    local output_dir="${1:-/tmp/screenshot}"
    local img_name="${2:-Screenshot}"
    local img_ext="${3:-png}"
    
    # create output directory (if not already existing)
    mkdir -p "${output_dir}"

    # get the last image in the sorted ls output
    local latest_png=$(tail -n 1 \
        <(sort -n -t _ -k 2 \
        <(ls ${output_dir}/*.${img_ext} 2> /dev/null)))

    # use the latest image to determine img_cnt value for next image
    local img_cnt=0
    if [[ ${latest_png} =~ _([0-9]+)\.png ]]; then
        img_cnt=$((1+${BASH_REMATCH[1]}))
    elif [[ ${latest_png} =~ ${img_name}.${img_ext} ]] ; then
        img_cnt=1
    fi

    # build path to output image
    local img_path="${output_dir}/${img_name}_${img_cnt}.${img_ext}"
    
    # remove count from output image path if count == 0
    if [[ "${img_cnt}" -eq "0" ]] ; then
        img_path="${output_dir}/${img_name}.${img_ext}"
    fi        

    xfce4-screenshooter -f -s "${img_path}"
}

capture_screenshot "$@"

使用以下作为默认值,但您可以更改它们以满足您的要求。

截图输出目录:
/tmp/screenshot

基本截图图片名称:
Screenshot

截图文件扩展名:
.png

如果输出目录尚不存在,脚本将尝试创建输出目录(取决于用户的创建权限)。下面是一个示例用法。

在初始脚本执行之前,输出目录不存在:

$ ls screenshot
$

初始执行(创建目录并创建 Screenshot.png:

$ ./script.sh 
$ ls /tmp/screenshot/
Screenshot.png

后续执行:

$ ./script.sh 
$ ls /tmp/screenshot/
Screenshot_1.png  Screenshot.png
$ ./script.sh 
$ ls /tmp/screenshot/
Screenshot_1.png  Screenshot_2.png  Screenshot.png

【讨论】:

  • 看起来不错!但是如果在脚本第一次运行后删除了其中一个屏幕截图会怎样?
  • @ErikMD 不错。这是目前实施的一个有问题的场景。我今天晚些时候可能也有时间来处理这种情况。
猜你喜欢
  • 2014-12-02
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多