I want to write an expect script which can do some task and in the end change the directory and give control to the user. I tried using
spawn cd path\to\dir
interact
but i am still in the same directory.
Any leads on how to accomplish this using expect ?
To change the directory in an expect script, you don't need to use the keyword "spawn" it works without it.
You may be a little confused, because in the terminal, in which you are executing the script, you will stay in the same directory, but the script changed the directory in which it is doing things.
I suppose you have spawned some command (like ssh, bash) and the spawned command is still running. Then at the end you can do like this:
send "cd /some/dir\r"
interact
Related
I'm working on an interactive Ruby script, which build and packages resources. In the middle of the process, I'd like to drop into an interactive shell, but pre-cd'd into a specific working directory, as well as with an explanatory message (CTRL-D to continue). The interactive bash + given initial command is what's problematic.
Per the answer for doing something like this in Bash, given at https://stackoverflow.com/a/36152028, I've tried
system '/bin/bash', '--init-file', '<(echo "cd ~/src/devops; pwd")'
However, bash runs interactively but completely ignores the '<(echo "cd ~/src/devops; pwd")' section.
Interestingly system '/bin/bash', '--init-file complains if no argument is given, but literally anything runs bash, but with no initial command.
*Note that (--rcfile instead of --init-file) has the same effect.
Change the working directory of the Ruby script first, so that bash inherits the correct working directory.
curr_dir = Dir.pwd
Dir.chdir("#{Dir.home}/src/devops")
system "/bin/bash"
Dir.chdir(curr_dir) # Restore the original working directory if desired
Oh, this is probably far better (you can probably guess how little familiarity I have with Ruby):
system("/bin/bash", :chdir=>"#{Dir.home}/src/devops")
I am trying to write a script that opens a command-line application (sagemath in this case) which on start up will send a certain command down the pipe (attach a script) without closing the application at the end.
I tried something like:
#!/bin/bash
echo "load(\"script.sage\")" | sage
This, of course, opens sage load the script print the output of the script and closes sage. Adding & at the end of the last line didn't work.
I know that technically I can add this script to the list of scripts which are loaded on startup always but this is not what I want. I thought that it might be done be making a dynamic link at some directory to my script, but not sure if there is such a directory and where it is.
Any suggestions?
Edit:
I didn't know about Expect (I'm a youngster in linux). Reading about, following Mark's suggestion, it a bit I managed to solve this. If this is of any interest to anyone in the future then this does the trick:
#!/usr/bin/expect
set timeout 20
spawn sage
expect "sage:"
send "load(\"script.sage\")\n"
interact
#!/usr/bin/expect
set timeout 20
spawn sage
expect "sage:"
send "load(\"script.sage\")\n"
interact
You could use 'screen' depending on how dynamically you need this script to run. See http://linux.die.net/man/1/screen for info on how to use screen.
You can either:
Use nohup to start the program E.g., nohup "load(\"script.sage\")" | sage.
Or, you can use the disown command.
I am attempting to write an expect script, which executes/runs another shell script. This shell script configures an emulator, so the expect script is intended to automatically configure the emulator by sending back the appropriate data. However, when I wrote exec followed by the name of the shell script in my expect script, nothing happened. The console just sits and waits. Entering strings and whatnot does not appease the script. Failure to launch. DOA... I read from other posts that using exec is not a good fit when interacting with the subprogram is necessary.
Any advice for how I can execute the shell script within the expect script then?
Thanks!
If you want to interact with the shell script, you need to spawn it, then expect to see patterns and send responses.
If you're brand new to expect, check out the book "Exploring Expect" by the author of expect Don Libes.
I'm quite familiar with Dir.chdir("/xyz")
Unfortunately, this changes the directory of the process, but not actually the directory of the user. I'll make the following example to illustrate my need.
$~/: ruby my_script.rb
CHANGING TO PATH FOR USER NOT SCRIPT
$/Projects/Important/Path: pwd
$/Projects/Important/Path
See? I need the script to change the user's path. Performing system/backticks/Dir.chdir all adjust the process path, and end with the user sitting where they started, instead of the path I want them.
From what I've read exec was the way to go, since it takes over the existing process... but to no avail.
You can't, but you can do something which might be good enough. You can invoke another shell from ruby:
Dir.chdir("/xyz")
system("bash")
Running this will create a new bash process, which will start in the /xyz directory. The downside is that changing this process will bring you back to the ruby script, and assuming it ends right away - back to the bash process that started the ruby script.
Another hack that might work is to use the prompt as a hackish hook that will be called after each command. In the ruby script, you can write the new directory's path somewhere that can be read from both bash and ruby(for example a file - but not an environment variable!). In the PROMPT_COMMAND function, you check that file and cd to what's written there. Just make sure you delete that file, so you don't get automatically cded there after every command you run.
I'm trying to change the directory of the shell I start the ruby script form via the ruby script itself...
My point is to build a little program to manage favorites directories and easily change among them.
Here's what I did
#!/usr/bin/ruby
Dir.chdir("/Users/luca/mydir")
and than tried executing it in many ways...
my_script (this doesn't change the directory)
. my_script (this is interpreted as bash)
. $(ruby my_script) (this is interpreted as bash too!)
any idea?
Cannot be done. Child processes cannot modify their parents environment (including the current working directory of the parent). The . (also known as source) trick only works with shell scripts because you are telling the shell to run that code in the current process (rather than spawning a subprocess to run it). Just for fun try putting exit in a file you run this way (spoiler: you will get logged out).
If you wish to have the illusion of this working you need to create shell functions that call your Ruby script and have the shell function do the actual cd. Since the functions run in the current process, they can change the directory. For instance, given this ruby script (named temp.rb):
#!/usr/bin/ruby
print "/tmp";
You could write this BASH function (in, say, you ~/.profile):
function gotmp {
cd $(~/bin/temp.rb)
}
And then you could say gotmp at the commandline and have the directory be changed.
#!/usr/bin/env ruby
`../your_script`
Like this?
Or start your script in the directory you want it to do something.
Maybe I don't get your question. Provide some more details.