如何让 csh 获取文件然后进行交互?
简要说明
我如何(1)启动一个新的csh,(2)强制它执行一些不在任何.cshrc中的命令(尽管我可以安排它们位于要获取的非标准位置) (3)然后进行互动?
例如,除了 http: 中描述的文件之外,是否有任何方法可以让 csh 或 tcsh 起诉备用启动文件: //www.manpagez.com/man/1/tcsh/,这表示
我已经了解
启动和关闭 登录 shell 首先执行系统文件中的命令 /etc/csh.cshrc 和 /etc/csh.login。然后它执行命令 用户主目录中的文件:首先 ~/.tcshrc (+) 或者,如果 找不到~/.tcshrc,则~/.cshrc,则~/.history(或者的值) histfile shell 变量),然后是 ~/.login,最后是 ~/.cshdirs (或 dirsfile shell 变量的值)(+)。 shell 可能会读取 /etc/csh.login 之前而不是 /etc/csh.cshrc 之后,以及 ~/.login 之前而不是之后 ~/.tcshrc 或 ~/.cshrc 和 ~/.history(如果是) 编译;请参阅版本 shell 变量。 (+)
Non-login shells read only /etc/csh.cshrc and ~/.tcshrc or ~/.cshrc
详细信息
我是 bash 用户。但我在一家硬件公司工作,那里 (1) 很多人都是 csh 用户,(2) 许多 CAD 工具依赖于环境中的东西,例如模块系统。
许多食谱 - 例如人们解释如何做事的内部维基页面 - 都是从诸如
start a new shell or xterm
source /proj/Foo/setup.proj
source ~some_engineer/env/setup-for-this-tool
now run the tool
“环境变量经常发生冲突”之类的内容开始的。有时我必须删除所有 ~/.* 文件、重新使用 ssh 等。
我想自动化其中的许多操作。事实上,我已经自动化了其中的许多工作。然而,我必须使用expect(实际上是Perl CPAN Expect)来自动化它们,以假装自己是一个交互式用户。
在此过程中,我有自己的脚本clear-env,我经常用它来启动几乎没有环境变量的shell。如此使用:
clear-env -keep HOME -- csh
and then either pipe commands in through expect
or run interactively
这适用于自动化。但有时我确实需要交互 - 但只有在我加载了几行长源脚本名称之后。
我希望能够加载这些源文件,然后回退到交互式。
例如,我已经尝试过
clear-env -keep HOME -- csh -c 'source filename' -i
...
,或者,没有我的clear-env
csh -c 'source filename' -i
...
希望它会执行-c命令,然后变得交互式。但它只执行-c命令。
我已经能够通过我自己的 perl 脚本中的 Expect 向 csh 提供命令,该脚本读取我的 tty,然后通过 Expect 将命令通过管道传输到 csh 中。然而,这样我就失去了csh的交互功能。
还有更好的办法吗?某种说法是“从现在开始,我希望您将您的控制终端重新连接到另一个终端?”
谢谢。
顺便说一句,这对于其他 shell 也很有用。然而,根据我的经验,csh 用户最容易编写必须手动执行的配方。
——
也许我没说清楚:
我知道
exec tcsh -c "source stuff ; exec bash"
并且 exec csh -c "source stuff ; exec csh"
情况是我已经通过 Expect 使用“交互式”命令驱动了该工具、脚本。
现在,在完成伪交互式设置之后,终于我想恢复真正的交互式。基本上,将 shell 的控制终端从 Expect 使用的 pty 更改为真正的 pty。
我已经能够通过创建转发过程来做到这一点。
但我希望我能改变。或者做类似的事情
... long
... sequence
... of expect commands
exec csh -i < /dev/my-pty ...
BRIEF
how do I (1) start a new csh, (2) force it to execute a few commands that are NOT in any .cshrc (although I could arrange for them to be in a non-standard location to be source'ed) and (3) then go interactive?
E.g. is there any way to get csh or tcsh to sue alternate startup files other than those described at http://www.manpagez.com/man/1/tcsh/, which says
I already know about
Startup and shutdown
A login shell begins by executing commands from the system files
/etc/csh.cshrc and /etc/csh.login. It then executes commands from
files in the user's home directory: first ~/.tcshrc (+) or, if
~/.tcshrc is not found, ~/.cshrc, then ~/.history (or the value of the
histfile shell variable), then ~/.login, and finally ~/.cshdirs (or the
value of the dirsfile shell variable) (+). The shell may read
/etc/csh.login before instead of after /etc/csh.cshrc, and ~/.login
before instead of after ~/.tcshrc or ~/.cshrc and ~/.history, if so
compiled; see the version shell variable. (+)
Non-login shells read only /etc/csh.cshrc and ~/.tcshrc or ~/.cshrc
DETAIL
I'm a bash user. But I work at a hardware company, where (1) many people are csh users, and (2) many of the CAD tools depend on stuff in the environment, such as the modules system.
Many recipes - e.g. internal wiki pages where people explain how to do things - start off something like
start a new shell or xterm
source /proj/Foo/setup.proj
source ~some_engineer/env/setup-for-this-tool
now run the tool
Oftentimes the environment variables conflict; sometimes I have to delete all of my ~/.* files, ssh in afresh, etc.
I would like to automate many of these. Indeed, I have automated many of these. However, I had to automate them by using expect (actually, Perl CPAN Expect), to fake out being an interactive user.
Along the way, I have my own script clear-env that I often use to start a shell with almost no environment variables. Used thusly:
clear-env -keep HOME -- csh
and then either pipe commands in through expect
or run interactively
This works for automation. But sometimes I really do need to be interactive - but only after I have loaded several lines of long source script names.
I would like to be able to load thes source files, and then fall back to interactive.
E.g. I have tried
clear-env -keep HOME -- csh -c 'source filename' -i
...
or, without my clear-env
csh -c 'source filename' -i
...
hoping that it would execute the -c command and then become interactive. But it only executes the -c command.
I have been able to feed commands to csh via expect in a perl script of my own, that reads my tty, and then pipes the command into the csh via expect. However, then I lose the interactive features of csh.
Is there any better way? Some way of saying "From this point on, I want you to reconnect youir controlling terminal to this other terminal?"
Thanks.
By the way, this would be useful for other shells as well. However, it has been my experience that csh users are the most prone to writing recipes that must be manually executed.
--
Perhaps I am not being clear:
I know about
exec tcsh -c "source stuff ; exec bash"
and
exec csh -c "source stuff ; exec csh"
The situation is that I have already driven the tool, the script, a long way using "interactive" commands via Expect.
Now, after I have done that pseudo-interactive setup, finally I want to return to being truly interactive. Basically, changing the controlling terminal for the shell from the pty that Expect was using, to a real pty.
I have been able to do this by creating a forwarding process.
But I was hoping that I could switch. Or do something like
... long
... sequence
... of expect commands
exec csh -i < /dev/my-pty ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你走在正确的轨道上。您可以使用
expect
来执行此操作。关键是语句interact
。...当然,如果您的提示中出现
>
。这是使用expect
的主要问题,但有时您会陷入没有其他出路的情况。另外,您可能希望采取措施避免脚本命令污染您的
.history
文件,但您可能已经意识到这一点。You were on the right track. You can use
expect
to do this. The key is the statementinteract
.... if
>
is in your prompt, of course. This is the main problem with usingexpect
, but sometimes you're trapped in a situation with no other way out.Also, you might want to take steps to not pollute your
.history
file with scripted commands, but you're probably already aware of that.我也有同样的问题。我正在使用 bash,并且有一个软件包,该软件包仅在您处于 csh 提示符并获取名为
nemo_start
的文件时才有效。这就是解决方案:除非文件来源正确并保留环境变量和别名,否则此
tsf
命令将不可用。I had the same problem. I'm using bash, and have a software package that only works if you are at a csh prompt and source a file called
nemo_start
. This is the solution:This
tsf
command would not have been available unless the file was sourced properly and environmental variables and aliases kept.我已经成功地通过将 $HOME 设置为其他目录,并将 .cshrc 放入新的 $HOME 中来完成此操作,它可以执行您的操作想要,然后将 $HOME 设置回 ~$USER 并手动获取 $HOME/.cshrc。
这感觉非常恶心,但似乎有效。请注意,其他点文件(如 .history)可能会被破坏,具体取决于 shell 中的启动顺序,但如果您绝望并希望避免使用 expect,那么这是一个值得探索的想法。
当登录到共享测试帐户时,我开始使用它来共享我自己的用户的 .cshrc,使用如下内容:
(当然,在这种情况下,您需要帐户之间的开放权限,所以不要在安全系统上执行此操作。)
类似的原则可能适用于 bash 或其他 shell。
I have managed to do this by setting $HOME to some other directory, and put a .cshrc in that new $HOME which does what you want, then sets $HOME back to ~$USER and manually sources $HOME/.cshrc.
It feels awfully nasty but seems to work. Beware other dotfiles like .history may be broken depending on the startup sequence within the shell, but it's an idea to explore if you're desperate and want to avoid using expect.
I've started using this to share my own user's .cshrc when logging in to a shared test account, using something like this:
(Of course in this case you need open permissions between accounts, so don't do this on a secure system.)
Similar principles could presumably be applied to bash or other shells.
这可能无法解决您的问题,但如果您的目标是自动化“源”,那么您可以将其放在别名中:
~/.aliases
This may not solve your problem, but if your goal is to automate a "source", then you can put it in an alias:
~/.aliases
如果“source stuff”应该替换为 (csh) shell 脚本,那么您将处于一个 bash shell,该 bash shell 继承了“source stuff”在 tcsh 中设置的环境。 'exec' 意味着您最终不会遇到嵌套的 shell 进程。
Where 'source stuff' should be replaced with a (csh) shell script, this leaves you in a bash shell that inherits the environment set up in the tcsh by 'source stuff'. The 'exec's mean you don't end up with nested shell processes.