Dan*_*ell 1 startup scripts systemd
我创建了一个/etc/rc.local:
$ cat /etc/rc.local
#!/bin/bash
echo "Starting"
randomString=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
echo "Finished"
Run Code Online (Sandbox Code Playgroud)
这在交互式运行时运行:
$ /etc/rc.local
Starting
Finished: lkFcvByNaIu7zmxuCYB3BQmJ05LwuVWL
Run Code Online (Sandbox Code Playgroud)
但是,当从 systemd 运行时,它会挂起并且不会返回。
如果我 ctrl+C 看起来它挂在fold命令上:
$ systemctl status rc-local
? rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabl
Drop-In: /lib/systemd/system/rc-local.service.d
??debian.conf
Active: activating (start) since Mon 2019-03-11 12:04:06 UTC; 12s ago
Docs: man:systemd-rc-local-generator(8)
Cntrl PID: 936 (rc.local)
Tasks: 5 (limit: 1152)
CGroup: /system.slice/rc-local.service
??936 /bin/bash /etc/rc.local start
??952 /bin/bash /etc/rc.local start
??953 cat /dev/urandom
??954 tr -dc a-zA-Z0-9
??955 fold -w 32
Mar 11 12:04:06 ip-10-0-4-116 systemd[1]: Starting /etc/rc.local Compatibility...
Mar 11 12:04:06 ip-10-0-4-116 rc.local[936]: Starting
Run Code Online (Sandbox Code Playgroud)
$ ps -ef
root 936 1 0 12:04 ? 00:00:00 /bin/bash /etc/rc.local start
root 952 936 0 12:04 ? 00:00:00 /bin/bash /etc/rc.local start
root 953 952 47 12:04 ? 00:00:23 cat /dev/urandom
root 954 952 36 12:04 ? 00:00:18 tr -dc a-zA-Z0-9
root 955 952 10 12:04 ? 00:00:05 fold -w 32
Run Code Online (Sandbox Code Playgroud)
我真的不需要一个非常随机的字符串,所以我可以使用:
date | md5sum | cut -c -12
Run Code Online (Sandbox Code Playgroud)
生成一个字符串。这在由 systemd 运行时工作正常。但是知道为什么前面的命令会挂起会很有趣。
担!
恕我直言,cat /dev/urandom一定会永远持续下去,所以你应该使用一个命令先读取八十行随机内容,然后关闭输入。
使用简单的head -80您仍然有多余的字符不使用,但它不应该永远停止,因为它在 80 个换行符(或 CRLF)后关闭/dev/urandom。这是一个丑陋的黑客:
$ cat /etc/rc.local
#!/bin/bash
echo "Starting"
randomString=`head -80 /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
echo "Finished"
Run Code Online (Sandbox Code Playgroud)
恕我直言,后台任务中的行为是不同的,因为 systemd 不知道 cat /dev/urandom何时会完成从随机数设备的读取。看起来是一样的,但很明显,它不是。一旦最后一个 head 命令完成,您的脚本就依赖于中断管道,因此可移植性不可靠。它还可以以管道中先前命令已捕获并处理的“Broken Pipe”信号结束。在 systemd 运行的 init 脚本中,可能没有提供这种通信,并且cat /dev/urandom挂起,因为它没有收到SIGPIPE信号或其他东西......
希望这可以帮助。
这并不能保证[A-Za-z0-9]范围内的 32 个字符,但重点是关闭/dev/urandom而不是依靠SIGPIPE魔法来终止进程,这在后台似乎无法正常工作,没有控制终端。
你也可以这样做:
randomString=`head -80 /dev/urandom | md5sum | cut -c -12`
Run Code Online (Sandbox Code Playgroud)
就像你的第二个例子一样。它是随机的/dev/urandom。