MacOS 如何创建开机启动脚本如何创建开机启动脚本在 macOS 上，可以通过创建一个特定的脚本文件来实现开机启动脚本。以下是一些步骤来执行此操作：创建脚本文件：使用你喜欢的文本编辑器创建一个新文件，将其中包含要在开机时运行的脚本代码。添加执行权限：在终端中，使用 chmod +x 命令为你的脚本文件添加执行权限。例如，如果你的脚本文件名为 startup_script.sh，则可以运行以下命令：chmod +x startup_script.sh移动脚本文件：将脚本文件移动到 /Library/LaunchDaemons 目录中。你需要拥有管理员权限才能进行此操作。例如，使用以下命令完成：sudo mv startup_script.sh /Library/LaunchDaemons/设置脚本的拥有者和组：为了确保脚本在开机时能够正确地启动，你需要将其拥有者和组设置为 root。使用以下命令：sudo chown root:wheel /Library/LaunchDaemons/startup_script.sh创建一个属性文件：创建一个属性文件以告知系统如何在开机时运行你的脚本。在 /Library/LaunchDaemons 中创建一个新的属性文件，文件名以 .plist 结尾。例如，com.example.startup_script.plist。编辑属性文件：使用文本编辑器打开属性文件，并将以下内容粘贴到文件中，并根据需要进行修改：<?xml version="1.0" encoding="UTF-8"?> Label com.example.startup_script ProgramArguments /Library/LaunchDaemons/startup_script.sh RunAtLoad <true/> KeepAlive <false/> 在上述代码中，确保将 com.example.startup_script 替换为你想要的标识符，并且 /Library/LaunchDaemons/startup_script.sh 替换为你实际的脚本文件路径。设置属性文件的拥有者和组：使用以下命令设置属性文件的拥有者和组为 root：sudo chown root:wheel /Library/LaunchDaemons/com.example.startup_script.plist加载并启动脚本：使用以下命令加载属性文件，并启动脚本：sudo launchctl load /Library/LaunchDaemons/com.example.startup_script.plist这将使脚本在下次启动时自动运行。请注意，如果你需要通过 GUI 运行脚本或需要特定用户环境的权限，可能需要使用其他方法来实现开机启动脚本。上述步骤仅是一个基本示例来帮助你开始。适用什么版本的系统上述步骤适用于 macOS 的较新版本，包括 macOS Mojave、macOS Catalina和 macOS Big Sur。这些版本的 macOS 使用 Launchd 作为系统的 init 系统，负责管理开机启动以及其他系统进程。如果你使用的是较旧的 macOS 版本，例如 macOS Sierra 或更早的版本，可能使用的是旧的 init 系统（如init.d 或 rc.d）来管理开机启动脚本。在这种情况下，你需要使用相关的文档和方法来创建开机启动脚本。请注意，每个 macOS 版本都有不同的启动脚本安装和管理方式，因此确保参考适用于你当前 macOS 版本的相关文档和指南。以下可能是无用信息在 macOS 中，可以使用 launchd 工具来创建开机启动脚本。以下是创建开机启动脚本的步骤：打开终端应用程序。创建一个新的启动代理文件，例如 com.example.startup.plist：sudo vim /Library/LaunchAgents/com.example.startup.plist在文件中添加以下内容：<?xml version="1.0" encoding="UTF-8"?> Label com.example.startup ProgramArguments /path/to/your/script.sh RunAtLoad <true/> 将 /path/to/your/script.sh 替换为您的脚本路径。保存文件并退出编辑器。启动代理：launchctl load /Library/LaunchAgents/com.example.startup.plist检查代理是否已启动：launchctl list | grep com.example.startup如果输出中包含代理名称，则表示代理已成功启动。这样，每次启动 macOS 时，您的脚本都会自动运行。如果您想停止自动启动，可以使用以下命令：launchctl unload /Library/LaunchAgents/com.example.startup.plist
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 &
统计 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行：输出脚本开始和结束时间，以及本次运行时间。其中，运行时间通过结束时间和开始时间的时间戳相减得出。
删除某个目录下大小为 0 的文件#!/bin/bash # 删除某个目录下大小为 0 的文件 #/home/www/html 为测试目录,脚本会清空该目录下所有 0 字节的文件 dir="/home/www/html" find $dir -type f -size 0 -exec rm -rf {} \;删除当前目录下大小为 0 的文件find . -type f -size 0 -exec rm -rf {} \;
macOS 应用多开多开一个微信open -n /Applications/WeChat.app多开一个QQopen -n /Applications/QQ.app只要你内存足够，理论无限多开open 命令的使用方法open: invalid option -- l Usage: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-s <partial SDK name>][-b <bundle identifier>] [-a <application>] [-u URL] [filenames] [--args arguments] Help: Open opens files from a shell. By default, opens each file using the default application for that file. If the file is in the form of a URL, the file will be opened as a URL. Options: -a Opens with the specified application. -b Opens with the specified application bundle identifier. -e Opens with TextEdit. -t Opens with default text editor. -f Reads input from standard input and opens with TextEdit. -F --fresh Launches the app fresh, that is, without restoring windows. Saved persistent state is lost, excluding Untitled documents. -R, --reveal Selects in the Finder instead of opening. -W, --wait-apps Blocks until the used applications are closed (even if they were already running). --args All remaining arguments are passed in argv to the application's main() function instead of opened. -n, --new Open a new instance of the application even if one is already running. -j, --hide Launches the app hidden. -g, --background Does not bring the application to the foreground. -h, --header Searches header file locations for headers matching the given filenames, and opens them. -s For -h, the SDK to use; if supplied, only SDKs whose names contain the argument value are searched. Otherwise the highest versioned SDK in each platform is used. -u, --url URL Open this URL, even if it matches exactly a filepath -i, --stdin PATH Launches the application with stdin connected to PATH; defaults to /dev/null -o, --stdout PATH Launches the application with /dev/stdout connected to PATH; --stderr PATH Launches the application with /dev/stderr connected to PATH to --env VAR Add an enviroment variable to the launched process, where VAR is formatted AAA=foo or just AAA for a null string value.
收集各种类别非常好用的 Mac 应用程序、软件以及工具。
macOS安装jdk8使用 brew 安装 jdk8# 这个安装不了 brew cask install adoptopenjdk8# 2021 后使用下面的命令来进行安装 brew install --cask adoptopenjdk8 # 或者 brew install adoptopenjdk8
使用日期命令 (Use date commands)shell 中表示月末的方法 (The way to indicate the end of the month in the shell)Date Command in shell# macos [ "$(date -r "$(($(date '+%s') + 86400))" +%e)" -eq 1 ] && echo "macOS 月末" || echo "macOS 不是月末" # linux [ "$(TZ=IST-32 date +%e)" -eq 1 ] && echo "Linux 月末(时差法)" || echo "Linux 不是月末(时差法)" [ "$(date -d 'tomorrow' +%e)" -eq 1 ] && echo "月末tomorrow" || echo "不是月末tomorrow" [ "$(date -d 'next-day' +%e)" -eq 1 ] && echo "月末next-day" || echo "不是月末next-day"类似的有：命令描述date -d "yesterday"显示昨天的时间date -d "tomorrow"显示明天的时间date -d "1 hour"显示一小时后的时间date -d "2 day ago"显示二天前的时间date -d "3 month ago"显示三个月前的时间date -d "2 year"显示二年后的时间date -d "last friday"显示上个星期五的时间date -d "next week"显示下周的时间date -d "next month"显示下个月的时间date -d "fortnight"显示二周后的时间date -d "7/1 2 week"显示 7/1 起算的第二周参数说明如果需要以指定的格式显示日期，可以使用“+”开头的字符串指定其格式，详细格式如下：%n : 下一行 %t : 跳格 %H : 小时(00-23) %I : 小时(01-12) %k : 小时(0-23) %l : 小时(1-12) %M : 分钟(00-59) %p : 显示本地 AM 或 PM %r : 直接显示时间 (12 小时制，格式为 hh:mm:ss [AP]M) %s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数 %S : 秒(00-59) %T : 直接显示时间 (24 小时制) %X : 相当于 %H:%M:%S %Z : 显示时区 %a : 星期几 (Sun-Sat) %A : 星期几 (Sunday-Saturday) %b : 月份 (Jan-Dec) %B : 月份 (January-December) %c : 直接显示日期与时间 %d : 日 (01-31) %D : 直接显示日期 (mm/dd/yy) %h : 同 %b %j : 一年中的第几天 (001-366) %m : 月份 (01-12) %U : 一年中的第几周 (00-53) (以 Sunday 为一周的第一天的情形) %w : 一周中的第几天 (0-6) %W : 一年中的第几周 (00-53) (以 Monday 为一周的第一天的情形) %x : 直接显示日期 (mm/dd/yy) %y : 年份的最后两位数字 (00.99) %Y : 完整年份 (0000-9999)上述格式不必全都记住，只需要掌握几个常用的即可。例如%Y表示年，%m表示月，%d表示日，%H表示小时，%M表示分钟，%S表示秒，%s表示从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数，相当于time函数，%w表示一周中的第几天。
macOS Android 文件传输在Mac计算机和Android设备之间浏览和传输文件。天行建，君子以自强不息。下载 AndroidFileTransfer.dmg{file href="https://crm.gxusb.com/d/LanzuoCloud/application/MacOS/AndroidFileTransfer.dmg" type="justify-center"}AndroidFileTransfer.dmg{/file}{file href="https://wwo.lanzoue.com/iLhro0gupz5c" type="justify-center"}蓝奏云 AndroidFileTransfer.dmg{/file}支持macOS 10.7及更高版本。如何使用它下载应用程序。打开 AndroidFileTransfer.dmg。将 Android 文件传输 拖动到 应用程序 中。使用 Android 设备随附的 USB 电缆并将其连接到 Mac。双击 “Android 文件传输” 。浏览Android设备上的文件和文件夹并复制文件。获得更多帮助