shell脚本学习第二弹-神奇的cd

本文深入探讨了Shell脚本中cd命令的工作原理,解析了为什么脚本中的cd命令不会改变当前命令行的目录,以及如何通过source命令解决这一问题。文章详细讲解了Shell命令的三种类型:内建命令、shell函数和外部命令,以及它们在执行过程中的不同行为。

shell脚本学习第二弹-神奇的cd


前言:作为一个linux程序员,估计用的最多的命令就是cd了吧,我们试着用脚本编译一下:

  1 #!/bin/bash
  2 pwd
  3 
  4 cd /home
  5 pwd

我们看一下结果:

/data/shell
/home

但是我们本地的shell中执行pwd:

/data/shell

咦!!!什么鬼??


相信这个问题大家也有人遇到过,我们就从原理上一一深入理解,解决问题。


我们首先看看shell命令的种类:
1.内建命令,顾名思意,就是shell内部包含的命令,就比如我们的cd命令就是一种,它改变了shell的属性设置,内建命令在执行的时候没有进程的创建和销毁。
2.shell函数编写的程序代码,也就是我们要学习的shell脚本。
3.外部命令。这个是我们的主角,他是独立于shell的可执行程序,比如find等等。命令行在执行外部命令时,会创建一个进程,在执行过程中,就有了进程的创建和消亡。我们细细说明一下这个过程:(很重要)

  1. 创建一盒shell进程的子进程
  2. 在子进程中查找外部命令在文件中的位置
  3. 在子进程中,用新程序取代shell拷贝并执行相应的程序,父进程进入休眠状态,等待子进程完毕。
  4. 子进程销毁,返回
    我们会发现,在这个过程中,父进程的属性(也就是环境变量)没有改变,因为子进程没办法改变父进程的环境变量。

有了上面的基础,我们就只到为什么脚本中cd在当前命令行是无效的了。那么,想要他有效,还有一种办法,就是用source来执行。

source cd.sh
#或者 
. cd.sh 

source命令是直接可以改变环境变量的,运行在父进程上的,所以没有进程的销毁和创建的。

在 MacBook(macOS)上配置定时任务,最常用且可靠的方法是使用 **`cron`** 或更现代的 **`launchd`**。对于你的需求&mdash;&mdash;“每天早上 7 点执行一个 Shell 脚本”&mdash;&mdash;我们推荐使用 `crontab`,因为它简单直观。 --- ## ✅ 方法一:使用 `crontab` 配置定时任务(推荐新手) ### 步骤 1:编写 Shell 脚本 创建一个 shell 脚本文件,例如 `morning_job.sh`: ```bash # 编辑脚本 nano ~/morning_job.sh ``` 输入以下内容(示例): ```sh #!/bin/bash # morning_job.sh - 每天早上7点运行的任务 # 记录日志时间 echo "[$(date)] 早上好!开始执行每日任务..." >> /Users/你的用户名/morning_log.txt # 示例:运行 pytest(假设你有 Python 和 pytest) cd /Users/你的用户名/projects/mytest || exit /usr/bin/python3 -m pytest test_daily.py -v >> /Users/你的用户名/morning_log.txt 2>&1 # 也可以做其他事情,比如打开浏览器、提醒等 osascript -e 'display notification "测试已完成!" with title "Python 自动任务"' & ``` > 🔁 替换 `/Users/你的用户名/` 为你的实际路径(可用 `echo $HOME` 查看) #### 设置脚本可执行权限: ```bash chmod +x ~/morning_job.sh ``` --- ### 步骤 2:编辑 crontab 定时任务 macOS 内置了 cron,使用以下命令编辑计划任务: ```bash crontab -e ``` 这会打开默认编辑器(通常是 `vim`),添加如下一行: ```cron 0 7 * * * /Users/你的用户名/morning_job.sh ``` 📌 这表示:**每天 7:00 AM 执行一次该脚本** > 💡 如果你是第一次用 `vim`: > - 按 `i` 进入编辑模式 > - 输入上面那行 > - 按 `Esc`,然后输入 `:wq` 回车保存退出 --- ### 步骤 3:验证 cron 是否生效 查看当前用户的 cron 任务: ```bash crontab -l ``` 你应该能看到刚才添加的那一行。 ✅ 至此,系统会在每天早上 7 点自动运行你的脚本--- ## 📝 补充说明 ### ✅ 如何知道自己的用户名? ```bash echo $HOME # 输出如:/Users/john ``` 所以你的完整路径可能是 `/Users/john/morning_job.sh` --- ### ✅ 如何测试脚本是否能正常运行? 手动执行一下看看有没有错误: ```bash ~/morning_job.sh cat ~/morning_log.txt ``` 确保路径、Python 命令、pytest 文件都正确。 --- ### ✅ 可选:让 cron 发送邮件通知(高级) macOS 默认安装了 `mail` 工具,你可以让 cron 出错时发邮件给你。 在 `crontab` 中加上: ```cron MAILTO=your_email@example.com 0 7 * * * /Users/你的用户名/morning_job.sh ``` 但注意:本地邮件需要配置 MTA(如 postfix),否则可能无法发送。一般用于服务器调试。 --- ## ⚠️ 注意事项 | 问题 | 解决方案 | |------|----------| | 脚本不运行 | 检查路径是否绝对路径,不要用 `~` | | 环境变量不同 | cron 的 PATH 很小,建议使用全路径调用命令(如 `/usr/bin/python3`) | | 权限问题 | 确保脚本有执行权限:`chmod +x script.sh` | | 不通知? | GUI 应用(如 `osascript`)需指定用户环境,见下方 `launchd` 更适合 GUI | --- ## ✅ 方法二:使用 `launchd`(macOS 原生方式,适合开机自启或唤醒后运行) 如果你希望 Mac **从睡眠中唤醒也能运行任务**,或者要触发 GUI 提醒,应使用 `launchd`。 ### 示例:创建 `~/Library/LaunchAgents/com.user.morningjob.plist` ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.user.morningjob</string> <key>ProgramArguments</key> <array> <string>/Users/你的用户名/morning_job.sh</string> </array> <key>StartCalendarInterval</key> <array> <dict> <key>Hour</key> <integer>7</integer> <key>Minute</key> <integer>0</integer> </dict> </array> <key>RunAtLoad</key> <false/> <!-- 可选:如果电脑当时休眠,唤醒后也运行 --> <key>KeepAlive</key> <false/> </dict> </plist> ``` ### 加载任务: ```bash # 加载 plist 文件 launchctl load ~/Library/LaunchAgents/com.user.morningjob.plist # 立即启动测试(可选) launchctl start com.user.morningjob # 卸载(修改后需要先卸载再加载) launchctl unload ~/Library/LaunchAgents/com.user.morningjob.plist ``` > ✅ `launchd` 更强大,支持休眠恢复后补执行,适合桌面自动化。 --- ## ✅ 总结对比 | 方式 | 易用性 | 推荐场景 | |------------|--------|-----------| | `crontab` | ✅✅✅ 简单直接 | 大多数定时脚本任务 | | `launchd` | ✅✅ 功能强 | 需要唤醒执行、GUI 交互 | | 第三方工具(如 Hazel、Keyboard Maestro) | ✅ 图形化 | 不想写代码 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值