我相信您的问题是,在screen以分离模式启动时,screen不会启动登录 shell 或交互式 shell,因此您的不是来源(有关启动时来源文件的说明,.bash_profile请参阅的“INVOCATION”部分) man bash. 请注意,-您的前导
shell -$SHELL
设置意味着 shell 将始终作为登录 shell 启动,因此.bash_profile将被获取。
您的问题的一些可能的解决方案:
不要screen以分离状态开始。请注意screen,如果脚本作为命令给出,则在以通常方式启动时脚本完成时终止。例如,对于脚本test.sh:
#!/bin/bash
for n in `seq 1 5`; do
echo $n
sleep 1
done
运行screen ./test.sh脚本并在 5 秒后终止。
.bash_profile在屏幕中运行的脚本中手动获取您的源代码。即添加
source ~/.bash_profile
到脚本的开头,MyScript.
更新 1
我仍然怀疑问题是你.bash_profile的没有被加载,所以让我们确保你.screenrc 的被加载。尝试添加
screen touch /tmp/when-was-screen-rc-sourced
到你的最后,~/.screenrc然后做
screen MyScript
接着
ls -lt --full-time /tmp
尝试几种不同的方式启动屏幕,看看是否~/.screenrc真的无法加载。
同样,您可以添加一行
touch /tmp/when-was-bash-profile-sourced
到你的最后,~/.bash_profile看看什么时候加载。
更新 2
这是一个示例,显示screen当您有该行时确实运行您的脚本
screen touch /tmp/when-was-screen-rc-sourced
在你的末尾~/.screenrc。
这是测试文件test.sh:
#!/bin/bash
touch /tmp/when-did-test-sh-start
for n in `seq 1 5`; do
echo $n
sleep 1
done
touch /tmp/when-did-test-sh-finish
这是证据。跑步
$ touch /tmp/when-did-we-start; screen -d -m ./test.sh; sleep 6; ls -ltr --full-time /tmp | tail -n4
给出输出
-rw------- 1 collins collins 0 2013-11-06 14:43:03.643564802 -0800 when-did-we-start
-rw------- 1 collins collins 0 2013-11-06 14:43:03.659565385 -0800 when-was-screen-rc-sourced
-rw------- 1 collins collins 0 2013-11-06 14:43:03.671565892 -0800 when-did-test-sh-start
-rw------- 1 collins collins 0 2013-11-06 14:43:08.707770194 -0800 when-did-test-sh-finish
所以,我仍然认为问题与您的~/.bash_profile(或任何定义您丢失的环境变量的定义)未加载有关。
更新 3
在这一点上,可能更容易准确地理解你想要完成的事情,然后想出一个更好的方法来完成它。要做到这一点,提供一个最小的示例脚本来说明您的问题对您很有帮助(即,当您直接运行它时它可以工作,或者在启动屏幕后手动运行,但在通过screen ./example.shor直接运行时不起作用screen -d -m ./example.sh)。
但是,与此同时,这是另一个潜在的解决方法(您是否尝试过我上面的第二个原始建议,
~/.bash_profile直接在您的脚本中采购您的?):
使用 bash 运行您的脚本,明确地使 bash 交互和/或登录 shell。例如,对于交互式登录 shell
screen -d -m bash -i -I ./MyScript
有关bash 在什么模式下加载的文件的一个很好的总结,请参见
此处。根据man bash,该bash -i -I组合应该使 bash 在交互式登录模式下运行您的脚本,因此~/.bash_profile应该得到来源。