ffmpeg 挂起后台进程解决方法当你运行一个进程时,它有 3 个打开的管道: stdin， stdout 和 stderr。管道有一个内存缓冲区(Linux 上为 4 KB)，可以容纳一定数量的数据，下一个写操作将暂停，直到从管道的另一侧读取一些数据。ffmpeg 默认情况下启用与 stdin 的交互。在 Mac OS X 和 Linux 系统上，这会导致 ffmpeg 在后台运行的作业挂起。-stdinEnable interaction on standard input. On by default unless standard input is used as an input. To explicitly disable interaction you need to specify -nostdin.Disabling interaction on standard input is useful, for example, if ffmpeg is in the background process group. Roughly the same result can be achieved with ffmpeg ... < /dev/null but it requires a shell.-stdin启用标准输入交互。默认情况下打开，除非使用标准输入作为输入。要明确禁用交互，您需要指定-nostdin。禁用标准输入交互很有用，例如，如果 ffmpeg 在后台进程组中。使用 ffmpeg ... < /dev/null 可以获得大致相同的结果，但它需要一个 shell。https://ffmpeg.org/ffmpeg-all.html案例演示nohup ffmpeg -i "http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4.m3u8" -c copy -report "test.mp4" >> tset.log 2>&1 &# 结果 [1] 46346 [1] + suspended (tty output) nohup ffmpeg -i -c copy -report "test.mp4" >> tset.log 2>&1用pgrep -f -l ffmpeg查看 ffmpeg 进程46346 ffmpeg -i http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4.m3u8 -c copy -report test.mp4从日志看 ffmpeg 进程已被暂停。ffmpeg started on 2022-11-30 at 10:12:07 Report written to "ffmpeg-20221130-101207.log" Log level: 48 ffmpeg version 5.1.2 Copyright (c) 2000-2022 the FFmpeg developers built with Apple clang version 14.0.0 (clang-1400.0.29.102) configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1.2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox libavutil 57. 28.100 / 57. 28.100 libavcodec 59. 37.100 / 59. 37.100 libavformat 59. 27.100 / 59. 27.100 libavdevice 59. 7.100 / 59. 7.100 libavfilter 8. 44.100 / 8. 44.100 libswscale 6. 7.100 / 6. 7.100 libswresample 4. 7.100 / 4. 7.100 libpostproc 56. 6.100 / 56. 6.100进程已经挂起，ffmpeg 并没有正常运行。添加 < /dev/null后 ffmpeg 正常运行。nohup ffmpeg -i "http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4.m3u8" -c copy -report "test.mp4" >> tset.log 2>&1 </dev/null &# 结果 [2] 47243ffmpeg 运行日志ffmpeg version 5.1.2 Copyright (c) 2000-2022 the FFmpeg developers built with Apple clang version 14.0.0 (clang-1400.0.29.102) configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1.2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox libavutil 57. 28.100 / 57. 28.100 libavcodec 59. 37.100 / 59. 37.100 libavformat 59. 27.100 / 59. 27.100 libavdevice 59. 7.100 / 59. 7.100 libavfilter 8. 44.100 / 8. 44.100 libswscale 6. 7.100 / 6. 7.100 libswresample 4. 7.100 / 4. 7.100 libpostproc 56. 6.100 / 56. 6.100 [hls @ 0x7fcf132069c0] Skip ('#EXT-X-VERSION:3') [hls @ 0x7fcf132069c0] Skip ('#EXT-X-ALLOW-CACHE:NO') [hls @ 0x7fcf132069c0] Opening 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4-1669773166.ts?txspiseq=104016800799917470950' for reading [hls @ 0x7fcf132069c0] Opening 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4-1669773167.ts?txspiseq=104016800799917470950' for reading Input #0, hls, from 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4.m3u8': Duration: N/A, start: 3025.400000, bitrate: N/A Program 0 Metadata: variant_bitrate : 0 Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 1080x1920, 30 fps, 30 tbr, 90k tbn Metadata: variant_bitrate : 0 Stream #0:1: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp Metadata: variant_bitrate : 0 Output #0, mp4, to 'test.mp4': Metadata: encoder : Lavf59.27.100 Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1080x1920, q=2-31, 30 fps, 30 tbr, 90k tbn Metadata: variant_bitrate : 0 Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp Metadata: variant_bitrate : 0 Stream mapping: Stream #0:0 -> #0:0 (copy) Stream #0:1 -> #0:1 (copy) Press [q] to stop, [?] for help frame= 1 fps=0.0 q=-1.0 size= 0kB time=00:00:00.00 bitrate=34909.1kbits/s speed= 11x [hls @ 0x7fcf132069c0] Opening 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4-1669773168.ts?txspiseq=104016800799917470950' for reading [hls @ 0x7fcf132069c0] Skip ('#EXT-X-VERSION:3') [hls @ 0x7fcf132069c0] Skip ('#EXT-X-ALLOW-CACHE:NO') [hls @ 0x7fcf132069c0] Opening 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4-1669773169.ts?txspiseq=104016800799917470950' for reading [hls @ 0x7fcf132069c0] Opening 'http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4-1669773170.ts?txspiseq=104016800799917470950' for reading frame= 180 fps= 90 q=-1.0 size= 1536kB time=00:00:06.01 bitrate=2091.8kbits/s speed=3.01x ...用pgrep -f -l ffmpeg查看 ffmpeg 进程。47243 ffmpeg -i http://pull-hls-l11.douyincdn.com/third/stream-112056463879832028_or4.m3u8 -c copy -report test.mp4解决方法一如果在指令中添加-nostdin，选项会导致 ffmpeg 无法启用 stdin 交互，因此避免了挂起后台进程的问题。nohup ffmpeg -nostdin -i 源流地址 -c:v copy -c:v copy -f flv 推流地址 >> /dev/null 2>&1 &解决方法二设置输入重定向</dev/nullnohup ffmpeg -i 源流地址 -c:v copy -c:v copy -f flv 推流地址 >> /dev/null 2>&1 < /dev/null &
{github repo="jaywcjlove/linux-command"} logo Linux Command Logo. https://github.com/jaywcjlove Linux 命令大全搜索工具，内容包含 Linux 命令手册、详解、学习、搜集。
统计 shell 脚本运行时间，支持 MacOS 与 Linux 系统。starttime=$(date +'%Y-%m-%d %H:%M:%S') sleep 5 endtime=$(date +'%Y-%m-%d %H:%M:%S') if [[ $(uname -a) =~ "Darwin" ]]; then start_seconds=$(date -j -f "%Y-%m-%d %H:%M:%S" "$starttime" +%s) end_seconds=$(date -j -f "%Y-%m-%d %H:%M:%S" "$endtime" +%s) else start_seconds=$(date -d "$starttime" +%s) end_seconds=$(date -d "$endtime" +%s) fi echo 开始时间："$starttime" echo 结束时间："$endtime" echo "本次运行时间：$((end_seconds - start_seconds)) s"#!/bin/bash # -*- coding: utf-8 -*- # @Time : 2021/8/7 13:10 # @Description : 计算脚本运行时间 # 获取脚本开始时间 start_time=$(date +'%Y-%m-%d %H:%M:%S') # 模拟脚本运行 sleep 5 # 获取脚本结束时间 end_time=$(date +'%Y-%m-%d %H:%M:%S') # 判断操作系统类型，选择不同的时间转换命令 if [[ $(uname -a) =~ "Darwin" ]]; then # macOS系统使用date命令的-j选项进行时间转换 start_seconds=$(date -j -f "%Y-%m-%d %H:%M:%S" "$start_time" +%s) end_seconds=$(date -j -f "%Y-%m-%d %H:%M:%S" "$end_time" +%s) else # Linux系统使用date命令的-d选项进行时间转换 start_seconds=$(date -d "$start_time" +%s) end_seconds=$(date -d "$end_time" +%s) fi # 输出脚本开始和结束时间，以及运行时间 echo "开始时间：$start_time" echo "结束时间：$end_time" echo "本次运行时间：$((end_seconds - start_seconds)) s"注释如下：第1行：指定脚本解释器为bash。第2-4行：添加脚本的元信息，包括脚本名称、作者、版本等信息。第7行：获取脚本开始时间，并使用date命令的格式化选项将时间格式化为"YYYY-MM-DD HH:MM:SS"的形式。第10行：使用sleep命令模拟脚本的运行，这里设置为5秒。第13行：获取脚本结束时间，并使用date命令的格式化选项将时间格式化为"YYYY-MM-DD HH:MM:SS"的形式。第16-24行：判断操作系统类型，选择不同的时间转换命令。macOS系统使用date命令的-j选项进行时间转换，Linux系统使用date命令的-d选项进行时间转换。第27-29行：输出脚本开始和结束时间，以及本次运行时间。其中，运行时间通过结束时间和开始时间的时间戳相减得出。
shfmtshfmt 格式化 shell 程序{github repo="mvdan/sh"}shfmt --helpusage: shfmt [flags] [path ...] shfmt 格式化 shell 程序。 如果唯一的参数是破折号（'-'）或没有给出参数，将使用标准输入。 如果给定路径是目录，则将使用在该目录下找到的所有 shell 脚本。 --version 显示版本并退出 -l, --list 列出格式与 shfmt 不同的文件 -w, --write 将结果写入文件而不是标准输出 -d, --diff 格式不同时显示差异变化 -s, --simplify 简化代码 -mn, --minify 缩小代码以减小其大小 (implies -s) Parser options: -ln, --language-dialect str bash/posix/mksh/bats, default "auto" -p, --posix shorthand for -ln=posix --filename str provide a name for the standard input file Printer options: -i, --indent uint 0 表示制表符（默认），>0 表示空格数 -bn, --binary-next-line 像 && 和 | 这样的二进制操作可能另起一行 -ci, --case-indent 缩进 case 语句 -sr, --space-redirects 重定向运算符后跟一个空格 -kp, --keep-padding 保持列对齐填充 -fn, --func-next-line 函数左大括号放在单独的一行 Utilities: -f, --find 递归查找所有 shell 文件并打印路径 --tojson 将语法树作为类型化的 JSON 打印到标准输出 For more information, see 'man shfmt' and https://github.com/mvdan/sh.参考其他语言的规范，我选择了 4 个空格、重定向后留空格shfmt -d -i 4 -sr main.shshellcheck