惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
P
Proofpoint News Feed
WordPress大学
WordPress大学
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
腾讯CDC
罗磊的独立博客
P
Privacy International News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Latest news
Latest news
C
Cisco Blogs
Project Zero
Project Zero
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
博客园 - 叶小钗
Spread Privacy
Spread Privacy
博客园 - 三生石上(FineUI控件)
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tenable Blog
Know Your Adversary
Know Your Adversary
Security Latest
Security Latest
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
L
Lohrmann on Cybersecurity
IT之家
IT之家
T
Tor Project blog
S
SegmentFault 最新的问题
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
月光博客
月光博客
L
LINUX DO - 热门话题
C
CERT Recently Published Vulnerability Notes
T
Threat Research - Cisco Blogs
A
Arctic Wolf
D
DataBreaches.Net
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 【当耐特】
T
The Exploit Database - CXSecurity.com
T
Threatpost
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
博客园 - 司徒正美
Vercel News
Vercel News
H
Help Net Security
N
News and Events Feed by Topic
MyScale Blog
MyScale Blog
Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy & Cybersecurity Law Blog

lvbibir's Blog

shell | 磁盘空间分析脚本 Linux cat 和 tee 命令写入文件 python | 使用 uv 管理你的 python 环境 Claude Code 完整配置指南 windows | mihomo 内核独立部署指南 linux | 磁盘扩容 wsl | 释放长久运行占用的磁盘空间 mysql | 线程上限问题处理 麒麟 7.6 安装谷歌 OTP 认证模块 suse 12sp5 升级 openssh 及 openssl suse 12sp5 部署 mysql 5.7 《谁的青春不迷茫》 docker | centos7 部署 docker vim | 基础配置和使用 windows | rime 输入法 & 雾凇方案 shell | sshpass 批量传输文件及执行命令 wsl | 原生 linux 方式安装 docker nodejs | fnm + pnpm 开发环境配置 wsl | 安装配置 miniconda 虚拟环境 wsl | 自动更新系统代理 wsl | bashrc 环境变量不正确加载的处理方法 wsl | win10 安装 wsl2 troubleshooting | ssh 成功但是 scp 失败 linux | 常用命令总结 docker 部署 piclist shell | 检测网站存活并自动钉钉告警 Zabbix | 监控端口连通性并自动追踪 TCP 路由 windows | 自定义开机快速启动项 windows | miniconda 配置 python 虚拟环境 Zabbix | 监控主机到指定 ip 的流量大小 shell | centos 初始化 loki (二) 部署 loki (一) 简介 prometheus (六) Alertmanager prometheus (五) 记录规则与告警规则 prometheus (四) 黑盒监控 prometheus (三) 服务发现 prometheus (二) 静态配置 prometheus (一) 简介及部署 traefik (四) TraefikService 服务 traefik (三) Middleware 中间件 traefik (二) ingressRoute 路由 traefik (一) 简介、部署和配置 kubernetes | Gateway API 简介及部署 linux | dns 配置文件中 search 和 options ndots 详解 kubernetes | command args 和 dockerfile 中的 ENTRYPOINT CMD kubernetes | statefulset 控制器详解 docker | dockerfile 最佳实践 docker | dockerfile 指令详解 linux | kill 命令详解以及 linux 中的信号 troubleshooting | elasticsearch 安装插件报错 shell | if 条件判断 docker | 下载外网镜像的几种方式 python | 鬼谷子数学问题 steam挂刀教程 linux | history 命令的格式化输出 shell | 将本地镜像批量推送到 harbor windows | hosts 文件修复 kubernetes | configmap & secret kubernetes | RBAC 鉴权和 NetworkPolicy kubernetes | service & ingress kubernetes | 存储 kubernetes | 滚动升级和自动伸缩 kubernetes | 控制器 kubernetes | 日志 kubernetes | 调度 kubernetes | pod kubernetes | 杂记 linux | set 命令详解 ceph | openeuler 部署 ceph-v16 ceph | ceph-v16 离线安装解决方案 pxe 如何应对复杂的服务器硬件环境 python | 批量修改目录下文件名 《微习惯》 ceph | openeuler (aarch64) 部署 ceph-v16 troubleshooting | glibc 误升级后修复 pxe 安装配置大全 《人间失格》 跑步日常 [置顶] Hello, hugo! shell | 检索某 url 中所有文件的内容 shell | 开启 debug 模式 vscode | 常见问题 windows & linux 多网卡时设置默认路由以及添加静态路由 mysql (二) 主从复制原理 GTID 并行复制 mysql (一) 部署 mysql | 杂记 cicd | jenkins 部署 mall-swarm 项目 httpd 源码打包编译成 rpm 包 openssl 源码打包编译成 rpm 包 centos7 | 修改网卡名称 ceph | pool pg_num 配置 docker | 脚本方式批量导出/导入镜像 centos 密码尝试次数过多问题处理 centos7 | 升级内核至 5.10 CVE-1999-0526 ceph | centos7 部署 ceph-v12 python | 修改 pip 源 troubleshooting | 安装 cloud-init 后导致 ssh 连接失败 windows | autohotkey 常用脚本
shell | 不同执行方式的区别
lvbibir · 2022-06-01 · via lvbibir's Blog

0 前言

本文参考以下链接:

1 不同的执行方式

shell 脚本通常有 sh filenamebash filename./filenamesource filename 这四种执行方式

  • source filename 可以使用 . filename 代替,在当前的 bash 环境下读取并执行脚本文件中的命令,且脚本文件的变量,在脚本执行完成后会保存下来
  • ./filenamesh filename 或者 bash filename 是等效的,都是开启一个子 shell 来运行脚本文件,脚本中设置的变量执行完毕后不会保存

./filename 外,source filename. filenamesh filenamebash filename 都是不需要执行权限的

变量和权限问题示例

# 设置临时变量,仅在当前 bash 环境生效
[root@lvbibir ~]# name=lvbibir
[root@lvbibir ~]# echo $name
lvbibir
[root@lvbibir ~]#
[root@lvbibir ~]# cat test.sh
#!/bin/bash
echo $name

# source 或者 . 可以获取到父 bash 环境的变量
[root@lvbibir ~]# source test.sh
lvbibir
[root@lvbibir ~]# . test.sh
lvbibir

# sh、bash、./三种方式都使用了子 bash 环境,所以无法获取父 bash 环境的变量
# ./ 方式需要脚本有执行权限
[root@lvbibir ~]# sh test.sh

[root@lvbibir ~]# bash test.sh

[root@lvbibir ~]# ./test.sh
-bash: ./test.sh: Permission denied
[root@lvbibir ~]# chmod a+x test.sh
[root@lvbibir ~]# ./test.sh

同理,使用 source 或者 . 也可以在 bash 环境中获取到脚本中设置的变量

[root@lvbibir ~]# cat > test.sh << EOF
> #!/bin/bash
> number=22
>
> EOF
[root@lvbibir ~]# echo $number

# sh bash ./ 三种方式无法获取脚本中的变量
[root@lvbibir ~]#
[root@lvbibir ~]# sh test.sh
[root@lvbibir ~]# echo $number

[root@lvbibir ~]# bash test.sh
[root@lvbibir ~]# echo $number

[root@lvbibir ~]# ./test.sh
[root@lvbibir ~]# echo $number

# source 方式可以获取脚本中的变量
[root@lvbibir ~]# source test.sh
[root@lvbibir ~]# echo $number
22
[root@lvbibir ~]#

2 其他问题

关于是否在子 bash 环境运行的区别出了变量问题还会存在一些其他影响,如下测试

已知目前存在一个 mysqld 进程,其 pid 为 29426 ,写一个监控 pid 的脚本

[root@lvbibir ~]# cat test.sh
#!/bin/bash
process=$1
pid=$(ps -elf | grep $process | grep -v grep | awk '{print $4}')
echo $pid

两种方式分别运行一下

[root@lvbibir ~]# sh test.sh mysqld
27038 27039 29426
[root@lvbibir ~]# bash test.sh mysqld
27047 27048 29426
[root@lvbibir ~]# ./test.sh mysqld
27056 27057 29426
[root@lvbibir ~]#
[root@lvbibir ~]# source test.sh mysqld
29426
[root@lvbibir ~]# . test.sh mysqld
29426
[root@lvbibir ~]#

问题出现了,由于某种原因导致子 bash 环境中执行的脚本监控到多个 pid ,给脚本添加个 sleep 来看下

[root@lvbibir ~]# cat test.sh
#!/bin/bash
process=$1
pid=$(ps -elf | grep $process | grep -v grep | awk '{print $4}')
echo $pid
sleep 30

[root@lvbibir ~]# ./test.sh mysqld
27396 27397 29426

新开一个终端,查看进程

image-20220630160731914

  • 第一个 pid 是在子 shell 中执行监控脚本的进程号
  • 第二个 pid 不太清楚哪里来的,也 grep 不到这个进程号,应该是脚本执行一瞬间就释放掉了
  • 第三个 pid 是 mysql 实际运行中的进程号

实际中脚本的 pid 和 mysqld 的 pid 顺序不太一样,取决于 pid 的大小

在脚本再添加个 grep 过滤掉脚本本身的进程来规避这个问题

[root@lvbibir ~]# cat test.sh
#!/bin/bash
process=$1
pid=$(ps -elf | grep $process | grep -v grep | grep -v bash | awk '{print $4}')
echo $pid

[root@lvbibir ~]# ./test.sh mysqld
29426

以上

wechat_pay

微信

alipay

支付宝