Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用exec函数启动登录shell(csh)?_C_Linux_Bash_Shell - Fatal编程技术网

如何使用exec函数启动登录shell(csh)?

如何使用exec函数启动登录shell(csh)?,c,linux,bash,shell,C,Linux,Bash,Shell,我已经知道,我可以使用参数-l启动bash或ksh作为登录shell,因此我不必为~/.profile,~/.bash\u profile等文件提供源代码。但是在csh中,这个句子 execl("/bin/csh","csh","-l","-c","env",NULL); 是错误的,是错误的信息 Unknown option: `-l' 但是我查了一下,发现-l的意思是 “外壳程序是登录外壳程序。仅当指定的唯一标志为-l时才适用。” 所以我把句子改成 execl("/bin/csh","cs

我已经知道,我可以使用参数
-l
启动
bash
ksh
作为登录shell,因此我不必为
~/.profile
~/.bash\u profile
等文件提供源代码。但是在csh中,这个句子

execl("/bin/csh","csh","-l","-c","env",NULL);
是错误的,是错误的信息

Unknown option: `-l'
但是我查了一下,发现
-l
的意思是

“外壳程序是登录外壳程序。仅当指定的唯一标志为
-l
时才适用。”

所以我把句子改成

execl("/bin/csh","csh","-l",NULL);


但是当我运行这个程序时,它暂停了。你能告诉我怎么解决吗?

试着这样运行:

execl("/bin/sh","sh","-l","-c","exec csh -l",NULL);

顺便问一下,你怎么知道其他shell的
-l
是解决方案

如果要捕获已登录用户获得的实际环境,则需要登录该用户。PAM(Pluggable Authentication Module,可插拔认证模块)可以并且确实在登录时设置环境变量,而仅仅执行shell不会触发这些环境变量

一种方法是创建一个伪终端,并运行
/bin/login-f username
(具有root权限,标准流对从伪终端打开)登录指定用户
-f username
应该告诉
login
用户已经过预验证,因此不应该显示密码对话框。写入主伪终端的所有内容都像用户输入的一样;从主伪终端读取得到输入(因为输入通常会回显到终端)以及结果

困难在于必须同时读写伪终端;绝对没有可靠的订单可以使用。(您需要将希望作为用户运行的命令写入伪终端主机,并读取结果输出。)此外,没有简单的方法知道shell命令何时完成;它是完全异步的

您无法使用
env
可靠地重建环境,因为环境变量可以包含换行符,
env
不会以任何方式转义它们。因此,您可能应该改用助手可执行文件。(环境名称-值对可以包含除ASCII NUL以外的所有内容
\0
,因此使用NUL分隔符输出所有环境名称-值对将起作用;Linux内核还以该格式提供了
/proc/self/environ

如果父进程生成一个临时文件名,并提供一个命令来执行将NUL分隔的环境名称-值对写入指定文件的帮助程序,例如,
“/usr/local/bin/envpairs0/tmp/tempfile\n logout\n”
,则当子进程退出时,任务就完成了。然后,您只需清理伪终端,读取并删除包含该用户环境的临时文件

正如你所看到的,这是相当复杂的。它在脚本语言(如Python)中稍微简单一些,因为Python支持伪终端(例如,请参见
pty
Python模块)。由于不知道您需要用户环境做什么,尤其是这是一次性事件还是定期需要,我很难给出更好的建议


我可以向您展示一个关于如何实现这一点的示例程序,但我有点担心,因为这里显然对这些复杂而冗长的示例抱有敌意。也许你应该考虑一个更简单的方法来实现你的目标?

你确切的意思是什么?进程不退出?过程的状态是什么?文件描述符(
ls/proc/$PID/fd
)上有什么内容?最后两个
execl()
调用中的哪一个显示了问题?我必须使用ctrl+c来停止它。它只是提醒我您以前的线程。:)我希望这个能帮助你。谢谢你的回复。情况是,我有一个进程a,它以root用户身份启动,因为用户可能会切换帐户,所以当前用户是不确定的。进程A现在需要使用当前用户的环境变量来派生一个新的进程B,所以我必须派生一个进程C来获取环境变量并将它们传输到进程A,这样A就可以使用这些变量来派生B。这就是我想要做的吗?你能给我一些建议吗?@BreakingDawn:“因为用户可能会切换帐户”——怎么做?也许您希望将服务分为两部分:作为root用户运行的特权部分,以及用户启动(或由用户配置文件自动启动)的跟踪/非特权部分。或者您可以跟踪用户进程,并从
/proc/PID/environ
中窥探其环境。或者,您可以使您的流程成为类似于
sshd
的全面服务,使其具有PAM意识。。更多细节可能会有所帮助。目的是什么?只需使用“su”切换帐户,但正在运行的进程A是由root启动的。进程A希望使用当前用户的环境变量来派生新进程B。当前用户是什么?即使使用桌面环境(通过X11转发),也可以有任意数量的用户登录到一台计算机上,有的从控制台登录,有的远程登录,有的通过SSH登录。听起来确实像是在跟踪用户控制的进程,使用它的
/proc/PID/environ
,可能是最简单的选择。@BreakingDawn:你知道这个进程还是跟踪用户控制的进程吗?
execl("/bin/sh","sh","-l","-c","exec csh -l",NULL);