基于 Bash 的随机密码生成器实战:从 /dev/urandom 到完整脚本
【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting
导读
本文将基于开源电子书《Introduction to Bash Scripting》(本仓库即为其源码与内容所在)中的「Bash Password Generator」章节,完整讲解如何在终端中用 Bash 一行命令生成随机密码,并逐步构建一个可交互的密码生成脚本。读者读完将掌握date、openssl rand、/dev/urandom三种随机源的核心差异,理解tr、fold、head管道组合的用法,并拿到一份开箱即用的完整脚本。
为什么需要 Bash 生成随机密码
在安装软件或注册网站时,我们几乎总会遇到"设置密码"的场景。获取随机密码的途径有很多:可以使用密码管理器/保险库(password manager/vault)中内置的随机生成功能,也可以借助在线网站代为生成。
但别忘了,终端本身就是一件强大的工具。通过 Bash 在命令行中生成密码,你既不需要依赖第三方服务,也能在写脚本的过程中加深对管道、重定向、伪随机源的理解。本仓库的电子书目录ebook/en/content/022-bash-password-generator.md详细介绍了多种实现方案,并留给你自己判断哪种最贴合需求。
⚠️ 安全须知:脚本仅供练习,勿明文保存密码
在动手之前,请先明确一点:本章脚本旨在练习你的 Bash 脚本技能。你可以通过这些小项目获得乐趣,但安全不是儿戏——请务必不要把密码以明文形式保存在本地文件中,也不要手写在纸上。
作者在章节中给出的明确建议是:请使用安全且受信任的服务商来生成和保存密码。脚本适合学习管道、循环和用户输入,但生产环境中的密码管理请交给专业的密码管理器。
脚本功能速览
在进入代码之前,先明确脚本要做什么:
- 脚本执行时,交互式地询问用户希望密码包含多少个字符;
- 按照第 1 步指定的长度,生成10 个随机密码(章节开头概要中写的是 5 个,完整脚本中实际为 10 个,以完整脚本为准)。
前置条件
- 一个可用的Bash 终端与任意文本编辑器(vi、vim、nano、Visual Studio Code 均可);
- 作者在本地 Linux 笔记本上运行该脚本;如果你使用 Windows,也可以 SSH 到任意一台服务器上执行;
- 脚本本身很简单,但具备一些基础 Bash 知识会帮助你更好地理解它。建议先阅读本仓库前序章节:Bash 变量、Bash 用户输入、Bash 循环,它们与本脚本涉及的
read -p和for循环直接相关。
生成随机字符串的三种方法
Linux 的一大好处是"条条大路通罗马"——生成随机字符串也不例外。以下逐一介绍,并给出真实示例输出。
方法一:用 date 命令配合哈希
date命令输出当前日期和时间。我们可以对输出进一步加工:用 md5、sha 哈希,或直接跑一遍 base64。
使用 md5sum:
date | md5sum 94cb1cdecfed0699e2d98acd9a7b8f6d -使用 sha256sum:
date | sha256sum 30a0c6091e194c8c7785f0d7bb6e1eac9b76c0528f02213d1b6a5fbcc76ceff4 -使用 base64:
date | base64 0YHQsSDRj9C90YMgMzAgMTk6NTE6NDggRUVUIDIwMjEK注意:
date的精度是秒级,同一秒内运行会得到相同结果;把它当作"随机源"在安全性上是有限的,这里更多是演示管道与文本转换。
方法二:用 openssl 生成伪随机字节
openssl rand可以直接生成伪随机字节,再通过 base64 编码输出:
openssl rand -base64 10 9+soM9bt8mhdcw==需要注意:openssl 可能没有预装在系统上,使用前可能需要先安装。
方法三(推荐):/dev/urandom + tr + fold + head
作者明确指出,最受推荐的方式是使用伪随机数生成器/dev/urandom,因为它面向绝大多数密码学用途。我们还需要借助tr对输出进行翻译/过滤:
tr -cd '[:alnum:]' < /dev/urandom | fold -w10 | head -n 1这条命令的运作逻辑(也是后面完整脚本的核心):
< /dev/urandom:把/dev/urandom的内容重定向为tr的标准输入(这是一种输入重定向,关于重定向的完整介绍可参考章节 Bash 重定向);tr -cd '[:alnum:]':-c取字符集的补集,-d表示删除。合起来的效果是"只保留字母和数字,删除其余所有字节";fold -w10:按宽度 10 折行,把连续字符流切成每行 10 个字符;head -n 1:只取第一行,即得到一个 10 字符的随机字符串。
字符集[:alnum:]对应字母(大小写)与数字,这正是绝大多数密码场景需要的可打印字符范围。
编写密码生成脚本
第一步:Shebang
脚本以 shebang 开头,它告诉操作系统用哪个解释器来解析文件其余部分:
#!/bin/bash第二步:询问用户密码长度
接着向用户询问输入——这里想知道密码需要多少个字符。使用read -p可以在读取输入前打印提示消息(-p标志的详细用法见 Bash 用户输入):
# Ask user for password length clear printf "\n" read -p "How many characters you would like the password to have? " pass_length printf "\n"clear清空屏幕,让界面更干净;read -p "..." pass_length把用户输入存入变量pass_length;- 上下各一个
printf "\n"用于留出呼吸感。
第三步:生成密码并打印
生成一组字符串,并按用户给定的长度截取:
# This is where the magic happens! # Generate a list of 10 strings and cut it to the desired value provided from the user for i in {1..10}; do tr -cd '[:alnum:]' < /dev/urandom | fold -w"${pass_length}" | head -n 1; done # Print a farewell message printf "Goodbye, %s\n" "$USER"for i in {1..10}循环 10 次,{1..10}的花括号展开语法在 Bash 循环 一章有专门讲解;fold -w"${pass_length}"把折行宽度改为用户指定的长度;- 每次循环生成一个随机密码并换行打印,共 10 个;
- 最后用
printf "Goodbye, %s\n" "$USER"打印告别消息,$USER是当前登录用户名(环境变量)。
完整脚本
将以上片段组合起来,就是章节中给出的完整版本:
#!/bin/bash #======================================= # Password generator with login option #======================================= # Ask user for the string length clear printf "\n" read -p "How many characters you would like the password to have? " pass_length printf "\n" # This is where the magic happens! # Generate a list of 10 strings and cut it to the desired value provided from the user for i in {1..10}; do tr -cd '[:alnum:]' < /dev/urandom | fold -w"${pass_length}" | head -n 1; done # Print a farewell message printf "Goodbye, %s\n" "$USER"保存为例如password-generator.sh,赋予执行权限后运行(赋予执行权限的方式可参考 Bash 参数 中的chmod +x示例):
chmod +x password-generator.sh ./password-generator.sh输入你期望的密码长度(比如 16),脚本会立刻输出 10 个 16 位随机密码,供你挑选使用。
深入理解:脚本背后的实现细节与质量保障
为什么推荐 /dev/urandom
章节明确推荐/dev/urandom,因为它"面向大多数密码学用途"。与date不同,/dev/urandom由内核持续收集熵并驱动伪随机数生成,不受秒级时间精度的限制;与openssl rand相比,它是 Linux 自带的虚拟设备,无需额外安装。这正是脚本选择它的根本原因。
字符集与密码强度
tr -cd '[:alnum:]'生成的密码只包含字母和数字(62 个字符),不包含!@#$%等特殊符号。若想包含特殊字符,可将[:alnum:]替换为更宽的 POSIX 字符类,例如[:graph:](所有可打印的非空白字符)或[:print:](所有可打印字符)。长度方面,章节给出的脚本完全由用户输入决定,建议实践中至少使用 12 位以上。
仓库中的脚本质量保障
本仓库不仅包含电子书正文,还在 scripts/shellcheck-ebook.sh 中提供了一个质量保障脚本:它从英文版电子书的 Markdown 文件中提取所有 ```bash 代码块,逐一用 ShellCheck 静态检查。运行方式:
./scripts/shellcheck-ebook.sh(默认扫描ebook/en/content目录,可通过参数指定其他目录。)
该脚本会跳过被标题标记为**Incorrect:**或### Error:的刻意错误示例,并对代码片段排除SC2034、SC2154等与"片段化教学"相关的告警码。这意味着本篇文章中的脚本风格(如单行for循环、printf告别消息)是经过 ShellCheck 验证、可安全运行的。如果你在本地修改脚本,也可以直接用shellcheck命令检查——这一建议同样出自本书的 调试与测试 章节。
已知局限与改进方向
章节作者在结论中坦率指出:当前脚本假设用户会提供符合预期的输入。例如:
- 如果用户直接回车(输入为空),
fold -w""会产生错误行为; - 如果用户输入了非数字字符,脚本同样不会拦截。
要避免这些问题,需要增加更高级的用户输入校验,确保即使输入不符合预期,脚本也能继续正常工作。可选的改进思路包括:
- 用
[[ -z "$pass_length" ]]判断是否为空(字符串表达式见 Bash 条件表达式); - 用
[[ "$pass_length" =~ ^[0-9]+$ ]]正则校验是否为纯数字; - 配合
while循环反复提示,直到输入合法(while循环的经典用法见 Bash 循环)。
结语与安全提醒
以上就是如何用一段简单的 Bash 脚本生成随机密码。最后再次强调章节中的两条安全忠告:
- 务必使用强密码,确保账户受到保护;
- 只要条件允许,尽量开启两步验证(2FA),它能为账户提供额外一层防护。
本脚本源自 022-bash-password-generator.md,是该开源 Bash 电子书"实战章节"的一部分——先学习前 13 章的基础语法(变量、输入、循环、条件),再动手实现这一类小工具,是掌握 Bash 脚本最有效的路径。
【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考