免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: FH
打印 上一主题 下一主题

关于 bash 模拟 sh 时针对环境变量的讨论 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2007-01-02 13:12 |显示全部楼层
原帖由 FH 于 2007-1-2 08:33 发表
当bash以sh为名运行时,在交互非login模式下,其继承了所有环境变量(包括任何用户定义的变量),唯独不继承PS*!
号称是靠向POSIX,但是俺用过的所有Unix(AIX、HPUX、SCO)的sh,在该模式下都是继承PS*变量的。 ...


其实,你的问题最有可能的只是,因为你当初用的系统都是把 PS1 宣告为 export/environment variable,而不是一般 local 性质变数,所以才会有这种差异。

这样吧?你还有在那些的 AIX,HUPX 等系统吗?你可不可以登入哪些系统后,执行 env | grep PS1 结果列一下呢 ? 这样一看就知道原因了。

--

[ 本帖最后由 kenduest 于 2007-1-2 13:15 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-01-03 01:09 |显示全部楼层
原帖由 FH 于 2007-1-2 21:19 发表
晕!
你自己试一下就知道了
俺Unix玩了十多年,Linux也玩了十年了,什么问题俺还看不清?


态度好像蛮高傲的 ?

PS1 本来就不是 export variable,所以怎么会有环境变量复制继承的特性呢?所以问题拉回来看,若你只是要能够 PS1 变量继承下去,请把 PS1 变量设定为 export variable 就可以了,不就是这样而已 ? 这样你就改改您 linux distro 的 bash 配置档即可,不是呼?

我都测试过了,于 bash 3 环境下把 PS1 变量设定为 export 变数后,就会具备复制继承的特性。

另外,也许该好好研究一下你的  .bashrc 配置,是否有改过 PS1 变量的程式码叙述。

--

[ 本帖最后由 kenduest 于 2007-1-3 01:18 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2007-01-03 16:25 |显示全部楼层
原帖由 FH 于 2007-1-3 09:39 发表
晕!你没看懂俺的问题吧?知道啥叫交互非login模式不?
你进vi,然后:!sh,再告诉俺有没有PS1!
真是你说的那么简单的事,俺都不好意思发帖子!


请上 GNU 的 coreutils mailing list 去回应你的问题,我想 developer 可以解决你的问题。因为在这边抱怨 bash 如何变态问题还是无解。

--

[ 本帖最后由 kenduest 于 2007-1-3 16:27 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-01-04 00:18 |显示全部楼层
原帖由 FH 于 2007-1-3 17:08 发表
看清楚好不好,俺给出了解决方案,而不是像某人那样问题都没有看清也不实验就开始信口开河。


看不出来你给了啥解决方案 ?

我等你好消息啊,不要忘记对 GNU coreutils mailing list 反应后的结果呈报一下。

--

论坛徽章:
0
5 [报告]
发表于 2007-01-04 09:40 |显示全部楼层
原帖由 FH 于 2007-1-4 08:58 发表
晕!4楼不是么?
就你这种看帖方式还申请版主?
但愿不要误杀、误导大家,阿门!


嗯,你说的好啊,所以我不申请版主了


--

论坛徽章:
0
6 [报告]
发表于 2007-01-10 02:28 |显示全部楼层
原帖由 FH 于 2007-1-9 19:19 发表
楼上的确很细致,佩服!
俺的是RHEL-AS4,俺也是man了以后找到的这个方法。
俺试了一下,如果直接在shell下面执行sh,是能够继承PS1的,但是进入了vi就不行了,从其它程序访问sh应该也是这样(推理),但是同样 ...


写个程式测看看不就知道了呼 ? 下面测试环境的 ENV 变数都没有指定任何内容。


  1. Linux:kendlee@~/tmp> cat test.c
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/wait.h>

  7. int main()
  8. {
  9.   pid_t child_p;

  10.   printf("getenv(\"PS1\") return %s\n\n",getenv("PS1"));

  11.   child_p = fork();

  12.   if (child_p == 0) {
  13.     printf("Executing sh program !\n");
  14.     execlp("sh","sh",NULL);
  15.   }

  16.   else {
  17.     waitpid(child_p,NULL,0);
  18.     printf("end... see you !\n");
  19.   }

  20.   return 0;
  21. }

复制代码


看一下执行结果,这是有是先把 PS1 设定为 export variable:


  1. Linux:kendlee@~/tmp> ./test
  2. getenv("PS1") result: Linux:\u@\w>

  3. Executing sh program !

  4. Linux:kendlee@~/tmp>
  5. Linux:kendlee@~/tmp> echo $PS1
  6. Linux:\u@\w>
复制代码


看起来 child process 还是有继承到。

再看看另外一个执行结果,这是有是先把 PS1 设定为一般变数,也就是取消非 export  variable 性质:


  1. Linux:kendlee@~/tmp> ./test
  2. getenv("PS1") result: (null)

  3. Executing sh program !

  4. sh-3.1$
复制代码


PS1 不是 export variable,所以 child 没有 PS1 变数继承下来,所以最终显示 sh$ 提示字元。

所以这边讨论来看,当初我最前面提到文章内部份的描述并没错误,这就是我会问你是否没有把 PS1 设定为 export variable 的原因点,只是你没正面回应我,只是一直告诉我搞不清楚何谓 interactive mode ... 因为实际一般测试方式就是在命令列输入执行 sh 来测试,为 export variable 时是会继承下去。

另外拿 mc 来测试一下好了...... 结果与上面也相同。

那问题拉回来看,是真的为变态的 bash 的问题吗?老实说我认为问题搞不好与 vi 本身有关系。

然后我去看了一下 vim7 的 source code :


  1.     if (execl("/bin/sh", "sh", "-c", cmd, NULL) == -1)
复制代码


发现原来是使用 /bin/sh -c 方式来执行命令,来看 bash manpage:


  1. An  interactive  shell  is one started without non-option arguments and
  2.        without the -c option whose standard input and error are both connected
  3.        to  terminals  (as determined by isatty(3)), or one started with the -i
  4.        option.  PS1 is set and $- includes i if bash is interactive,  allowing
  5.        a shell script or a startup file to test this state.
复制代码


所以因为有传 -c,这时候不是 interactive mode,简单说就是为 non-interactive mode。

那再看一下 bash info page 文件:


  1. Alternatively, startup scripts may examine the variable `PS1'; it is
  2. unset in non-interactive shells, and set in interactive shells.  Thus:

  3.      if [ -z "$PS1" ]; then
  4.              echo This shell is not interactive
  5.      else
  6.              echo This shell is interactive
  7.      fi

复制代码


所以说 non-interactive 时 PS1 会被 unset 而消失掉,所以不会有复制继承功能。

FH 兄你说会继承,这下真的奇怪了...... 若是真的会继承,那可能原因大概只有这点: "你系统用的 vi 程式码内容写法不一样",比方用 execlp 直接呼叫外部程式,不透过 sh -c 来达成,那我想这样 PS1 就真的会复制继承下去而不会被 unset 掉。

关于最后论点,其他人不知道有其他想法呼?

--

[ 本帖最后由 kenduest 于 2007-1-10 03:22 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-01-10 22:56 |显示全部楼层
原帖由 FH 于 2007-1-10 08:44 发表
to 楼上:
export PS1俺是绝对不会疏忽遗忘的,因此才有变态一说。
刚刚在SUSE LINUX Enterprise Server 9 (i586) - Kernel 2.6.5-7.97-bigsmp上试验,结果一如RHEL-AS4。


你可以把你说的 AIX 与 HPUX 环境测试 vi 执行使用 :!sh 后情况也贴出来一下吗?这样好判断问题点.

--

[ 本帖最后由 kenduest 于 2007-1-10 23:10 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP