我相信您的问题是,在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.sh
or直接运行时不起作用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
应该得到来源。