Allen Hua 的网络博客 - shell
type: channel
link: https://hellodk.cn/tag/shell/
items: 使用 exiftool 方便快捷写入图片的 exif metadata
items: 给 Java 应用和 React 应用部署 systemd 开机自启
items: 分享一个 git add、git commit、git push 的快捷工作流工具
items: 写shell脚本监测vps上的frps进程是否存在，不存在自动重启

使用 exiftool 方便快捷写入图片的 exif metadata
type: item
date: 2024-07-15T14:00:00+08:00
description: 我现在都在用 squoosh 批量压缩照片。但是 squoosh 压缩出来的图片丢失了 exif 数据，不论是网页还是终端 squoosh-cli。关于使用终端 squoosh-cli 批量压缩图片，你可以阅读我写的 [可能是]最好的压缩图片程序，使用 squoosh-cli 批量压缩图片 关于在得到压缩后的图片不丢失exif元数据这个问题，我尝试了其他压缩工具，比如 tinypng.com 也一样无法实现目的。 tinypng.com 的 web，压缩后的图片无法得到元数据。然后我关注到了其 API，https://tinypng.com/developers/reference/java 我写了段Java代码试了一下，通过调用方法 source.preserve("copyright", "creation", "location"); 可以保存元数据 System.out.println("start to tiny your images..."); try { String path = "c:\\users\\dk\\downloads\\IMG_1989.jpg"; Source source = Tinify.fromFile(path); String lowercasedPath = path.toLowerCase(Locale.ROOT); Source sourceWithMetadata; if (lowercasedPath.endsWith(".jpg") || lowercasedPath.endsWith(".jpeg")) { //location sourceWithMetadata = source.preserve("copyright", "creation", "location"); } else { sourceWithMetadata = source.preserve("copyright", "creation"); } sourceWithMetadata.toFile("c:\\users\\dk\\downloads\\IMG_1989-dk-compressed.jpg"); } catch (IOException e) { throw new RuntimeException(e); } 但是经过实践发现只保留下来了图片拍摄时间。我想要的相机信息，镜头信息，拍摄参数（比如快门时间、ISO大小、光圈大小）等还是丢失了。 经过一番研究，我最终转变了思路。 使用 exiftool 工具写入照片的原始exif metadata，我之前居然不知道 exiftool 这么好用的工具。 官网 https://exiftool.org/ ExifTool 由 Phil Harvey 开发，是一款免费、跨平台的开源软件，用于读写和处理图像（主要）、音视频和PDF等文件的元数据（metadata）。ExifTool可以作为Perl库（Image::ExifTool）使用，也有功能齐全的命令行版本。ExifTool支持很多类型的元数据，包括Exif、IPTC、XMP、JFIF、GeoTIFF、ICC配置文件、Photoshop IRB、FlashPix、AFCP和ID3，以及众多品牌的数码相机的私有格式的元数据。 本段介绍source 我在 squoosh 容器当中继续操作。 squoosh 容器基于 alpine 镜像制作，所以使用 apk 安装 exiftool 即可。 # apk add exiftool 然后编写一段 shell 脚本。 2024-08-02 19:18:18 新增一些说明 我做的 dko0/squoosh:v1.12.0 镜像是支持amd64, arm64 and arm v7 arch这三个架构的，但是只有在 arm64 机器上运行的容器安装了vim之后才能正常运行。在amd64机器上pull了此镜像后启动一个容器然后通过apk安装vim会无法运行，都会报错Segmentation fault (core dumped)。关于这个问题我检查了很多东西，发现可能是 alpine linux 和不同架构的相关依赖实现的问题 由于 Alpine Linux 使用的是轻量级的 musl libc，而不是更常见的 glibc，这可能会导致某些软件在运行时出现兼容性问题 alpine linux 默认使用 /bin/ash 作为 default shell，而且内置的 vi 等命令都是来自 busybox，简体中文不太好支持。所以下面的 shell 我最终改用 /bin/bash 编写。我放在宿主机 debian 执行了 debian 需要通过 apt-get u…

给 Java 应用和 React 应用部署 systemd 开机自启
type: item
date: 2021-12-29T10:59:00+08:00
description: 思路就是编写启动和停止的 shell 脚本，然后编写 systemd 配置文件。 我以我之前写的微博热搜实时推送前后端程序为?️。欢迎关注我的 微博热搜实时推送 tg 推送频道。 url is https://t.me/weibo_hot_search GitHub: https://github.com/hellodk34/weibo_hot_search 该 Java 应用是这样运行的 java -jar xxx.jar > /dev/null 2>&1 & 该 react应用是这样运行的 serve -s build > /dev/null 2>&1 & Java 应用 编写 start-wb-hotsearch.sh 文件 注意 jar 文件的绝对路径 #!/bin/bash /usr/local/java/jdk1.8/bin/java -jar /xxx/wb_hotsearch/wb-hotsearch-2021-12-22.jar > /dev/null 2>&1 & echo $! > /var/run/wbhotsearch.pid 编写 stop-wb-hotsearch.sh 文件 #/bin/bash PID=$(cat /var/run/wbhotsearch.pid) kill -9 $PID rm -rf /var/run/wbhotsearch.pid 编写 systemd service 文件 在 /usr/lib/systemd/system/ 下创建 wbhotsearch.service 文件，内容如下。注意两个shell文件的绝对路径要写对，下面给出的是假的路径 [Unit] Description=Weibo hot search back end After=network.target [Service] Type=forking ExecStart=/xxx/wb_hotsearch/start-wb-hotsearch.sh ExecStop=/xxx/wb_hotsearch/stop-wb-hotsearch.sh [Install] WantedBy=multi-user.target 配置 systemd 先执行 systemctl daemon-reload 再 enable 然后 start 即可。下面的 status 和 is-enabled 可以帮助查看服务状态 systemctl enable wbhotsearch systemctl start wbhotsearch systemctl status wbhotsearch systemctl is-enabled wbhotsearch React 应用 殊途同归，React 应用也是如此，下面简要写一下 编写 start-wbhotsearch-front.sh 文件 #!/bin/bash /usr/bin/serve -s /xxx/wb_hotsearch/wb-hotsearch-front-end/build > /dev/null 2>&1 & echo $! > /var/run/wbhotsearchfront.pid 编写 stop-wbhotsearch-front.sh 文件 #/bin/bash PID=$(cat /var/run/wbhotsearchfront.pid) kill -9 $PID rm -rf /var/run/wbhotsearchfront.pid 编写 systemd service 文件 在 /usr/lib/systemd/system/ 下创建 wbhotsearch-front.service 文件，内容如下。注意两个shell文件的绝对路径要写对，下面给出的是假的路径 [Unit] Description=Weibo hot search front end service After=network.target [Service] Type=forking ExecStart=/xxx/wb_hotsearch/wb-hotsearch-front-end/start-wbhotsearch-front.sh ExecStop=/xxx/wb_hotsearch/wb-hotsearch-front-end/stop-wbhotsearch-front.sh [Install] WantedBy=multi-user.target 配置 systemd 先执行 systemctl daemon-reload 再 enable 然后 start 即可。下面的 status 和 is-enabled 可以帮助查看服务状态 systemc…

分享一个 git add、git commit、git push 的快捷工作流工具
type: item
date: 2021-07-04T16:02:00+08:00
description: gitpushworkflow feature description: git add . and git commit -m and git push workflow 一个不是那么复杂的 git add .、git commit -m 'xxx'、git push 的工作流脚本工具。 工具：Click Me Usage 1. in macOS or any Linux systems cp linux-gitpush.sh to any folder you like, such as /path/of/linux-gitpush.sh at current git repo's work dir, just run bash /path/of/linux-gitpush.sh 2. in Windows cp windows-gitpush.bat to any folder you like, such as D:\, after copying, this file's absolute path is should be D:\windows-gitpush.bat at current git repo's work dir, and just run d:\windows-gitpush.bat Example in macOS or Linux this output is like this huadekaideMBP:notes-2021 huadekai$ bash linux-gitpush.sh this a git push workflow in macOS or Linux, using a shell file current time is: 2021-07-04 15:22:30 current work dir is: /Users/huadekai/Downloads/personal-projects/github/notes-2021 first step: git add . second step: git commit -m 'xxxx' [master b15a526] 2021-07-04 15:22:30 update 1 file changed, 1 insertion(+), 16 deletions(-) Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 12 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 293 bytes | 293.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To github.com:hellodk34/notes-2021.git 3c5905e..b15a526 master -> master third step: git push. ending. the end of the workflow. in Windows the output is like this D:\repo\github\notes-2021>windows-gitpush.bat this a git push workflow in Windows, using a bat file current time is: 07/04/2021 Sun 15:19:31.45 current work dir is: D:\repo\github\notes-2021 first step: git add . Waiting for 0 seconds, press CTRL+C to quit ... second step: git commit -m 'xxx' [master 9e9da30] 07/04/2021 Sun 15:19:33.16 update 3 files changed, 42 insertions(+), 13 deletions(-) Waiting for 0 seconds, press CTRL+C to quit ... third step: git push Enumerating objects: 9, done. Counting objects: 100%…

写shell脚本监测vps上的frps进程是否存在，不存在自动重启
type: item
date: 2021-06-07T10:06:00+08:00
description: 写下面文本到文件 /home/sftp/check_frps.sh #!/bin/bash # author: hellodk # time: 2021-05-28 16:14:26 # script feature description: check if frps is running, if not, start it function check_frps(){ time3=$(date "+%Y-%m-%d %H:%M:%S") frpsCount=`ps aux | grep "/usr/local/frp/frps -c /usr/local/frp/frps.ini" |grep -v grep |wc -l` if [ 0 == $frpsCount ]; then echo $time3 "current running frps process count: "$frpsCount ", meaning frps daemon is dead, now start it" >> /home/sftp/check_frps.log nohup /usr/bin/systemctl start frp >> /home/sftp/check_frps.log 2>&1 & else echo $time3 "current running frps process count: "$frpsCount ", and no need to start frps" >> /home/sftp/check_frps.log fi } check_frps 脚本是没有问题的，使用bash执行也是正常，日志打印也正常，但就是在我的那台硬件配置比较差的vps上总是无法使用 crontab 保存执行 每次使用 crontab -e 新增一行然后保存退出，成功提示crontab: installing new crontab 但是过了一段时间后发现这行就不见了…… 脚本自然也就没有按照预期执行。 由于这一台主机挂了京东薅羊毛的脚本，后续发现了问题所在。 在狗东薅羊毛控制面板（web端）直接编辑了这个cron list，成功新增一行，web的提示是成功修改了 crontab.list 文件，后面通过 find 命令找到了 # find / -name crontab.list /opt/jd/config/crontab.list 我应该直接修改这个文件，新增我的cron计划。 需要额外重点关注：crontab -e 命令编辑的文件是 /var/spool/cron 目录下的具体的用户名文件 比如 root, 具体文件是 /var/spool/cron/root 0 0-23/1 * * * bash /home/sftp/check_frps.sh, 含义是每隔一小时执行一次这个 shell 脚本 或者 0 */1 * * * bash /home/sftp/check_frps.sh 这两个命令都代表每隔一小时执行一次（也就是每小时检查一次frps进程是否存在） 将这行新增到 /opt/jd/config/crontab.list 文件末尾保存退出即可。后续查看脚本发现稳定运行~ 看看日志 # tail -n 15 /home/sftp/check_frps.log 2021-06-06 20:00:01 current running frps process count: 1 , and no need to start frps 2021-06-06 21:00:02 current running frps process count: 1 , and no need to start frps 2021-06-06 22:00:01 current running frps process count: 1 , and no need to start frps 2021-06-06 23:00:01 current running frps process count: 1 , and no need to start frps 2021-06-07 00:00:04 current running frps process count: 1 , and no need to start frps 2021-06-07 01:00:02 current running frps process count: 0 , meaning frps daemon is dead, now start it 2021-06-07 02:00:02 current running frps process count: …