我编写shell脚本来在OSX和Linux中做各种事情,但我总是遇到同样的问题。该脚本运行但它对环境所做的任何更改(当然除了磁盘)都不会“粘住”。当脚本终止时,更改将恢复。
如何更改我的更改?
编辑:很多答案都很棒,但他们没有帮助我今晚面临的情况。我正在尝试运行此操作以使我的TAP界面正常工作
sudo bash # we go superuser
exec 4<>/dev/tap0 # opens device, creates interface tap0
ifconfig tap0 10.10.10.1 10.10.10.255
ifconfig tap0 up
如果我将其粘贴,它的效果非常好,但如果我采购它或者它,则不会。顺便说一句,之后我无法关闭终端窗口,因为我丢失了tap0接口。
上次修改:感谢大家,答案是使用源代码,但是要从脚本本身删除sudo命令。
答案 0 :(得分:4)
这种行为是设计的 - 至少在bash中,这是我使用的,但我认为大多数shell的工作方式相同。通常,进程无法将环境变量等内容导出到其父进程。如果要在当前shell进程中运行一系列命令来更改环境,可以执行的操作是将命令写入文件并 source 。在bash中你输入
$ source commands.sh
或
$ . commands.sh
答案 1 :(得分:3)
子进程中对环境的更改不会影响父进程。幸运的是,您可以通过说
在当前进程中运行shell脚本. /path/to/script.sh
或
source /path/to/script.sh
但要小心,如果在脚本中运行exit
,它将退出当前shell。
答案 2 :(得分:2)
你的意思是环境变量中的'环境'吗?你不能,不是你的意思。那个“环境”是一个过程背景的东西;它对您的系统来说不是全局的,它是脚本特定执行环境的一部分。它可以传递给脚本启动的进程,但就是这样。如果要为环境变量设置可靠的设置,可以在系统共享初始化文件中执行此操作,如/ etc / profile和/etc/bash.bashrc(实际名称操作系统和安装依赖项)。不同的init脚本在不同的情况下运行(登录shell与衍生的shell,类似的东西),但我们的想法是你用你想要的环境上下文预先初始化shell。
答案 3 :(得分:2)
如果要在脚本中设置环境变量,它们只会在脚本运行期间保留。
如果您需要整个shell会话的环境变量,则需要在.profile,.bashrc,.tcshrc或.rc文件中设置它们,以用于您正在使用的任何shell。有关如何执行此操作的示例,请参阅“man <your shell>
”(例如man bash
)。
答案 4 :(得分:1)
这是设计的。
您可以将所需的“粘性”环境变量写入文件,并在下次运行时将其读入。例如:
#!/bin/sh
# load from ~/.my_env
[ -r ~/.my_env ] && . ~/.my_env
# replace or add new entries to ~/.my_env
for i in "$@"; do
[ "${i/=/}" = "$i" ] && continue
touch ~/.my_env
sed -i -e "\|^export ${i%%=*}=|d" ~/.my_env
echo "export $i" >> ~/.my_env
eval export "$i"
done
答案 5 :(得分:1)
您真正的问题似乎只是关于点击界面。您应该更改问题以反映这一点。
从Linux的Documentation / networking / tuntap.txt中阅读有关tap的文档。这是一个简短的引用:
“为了使用驱动程序,程序必须打开/ dev / net / tun并发出一个 相应的ioctl()用于向内核注册网络设备。一个网络 设备将显示为tunXX或tapXX,具体取决于所选的选项。什么时候 程序关闭文件描述符,网络设备和所有 相应的路线将消失。“
我会说非常直截了当。没什么神秘的。您的脚本会打开tap界面,当脚本退出时,会关闭文件描述符。
答案 6 :(得分:1)
当你sudo时,你必须明白你正在运行另一个程序,在这种情况下是另一个shell。误解在终端上粘贴这些命令与将它们放在脚本上是一样的误解。发生的事情是,在sudo之后,终端连接到另一个shell会话,第二个和更多命令被发送到另一个shell会话。如果将所有命令放在脚本上,则所有四个命令都在同一个shell会话上执行,从而产生不良结果。
在这种特定情况下,我建议你将最后三个命令放在另一个脚本上(例如setup-tap.sh),然后将该脚本调用为
sudo bash setup-tap.sh
如所建议的那样,Sourcing是在当前shell中持久更改脚本调用的替代方法,但在这种情况下它不起作用。它是一个级别,它可能会将你看作一个脚本,因为终端是相同的,但是在sudo之后,你不再是同一个shell了。
就像制作一个这样的剧本:
vi file.txt
iThe quick brown fox jumps over the lazy dog.<ESC>:wq
当然,第二行(vi命令)不会在vi中输入,它仍然在原始脚本中。
另一种选择是使用here-documents,并将特权命令从标准输入传递给sudo bash:
sudo bash <<-EOF
exec 4<>/dev/tap0
ifconfig tap0 10.10.10.1 10.10.10.255
ifconfig tap0 up
EOF