I am trying to write a Node.js script that will start a Node.js server in a new process, in a new command window.
I believe I am close. I have this:
var n = cp.spawn('sh', [ 'start-server.sh' ]);
the contents of start-server.sh are like so
#!/usr/bin/env bash
node bin/www
this starts the server successfully, but it doesn't open a new terminal window, so I can't see any of the stdio of the spawned process.
So I am thinking that I should open a new terminal window in the bash script and then run the node command, so then the bash script contents would become
#!/usr/bin/env bash
terminal -e "node bin/www"
the problem is that "terminal" is not recognized at the command line. Why is that? I believe the "terminal" command should default to whatever program is being used as your default terminal application.
Please advise if this is the best way to do this and why "terminal" might not be recognized at the command line in OSX, thanks!
this is what is in my path
echo $PATH
/Users/amills001c/.rvm/gems/ruby-2.2.1/bin:/Users/amills001c/.rvm/gems/ruby-2.2.1#global/bin:/Users/amills001c/.rvm/rubies/ruby-2.2.1/bin:/Users/amills001c/google_app_engine_stuff/google-cloud-sdk/bin:/usr/local/bin:/usr/local/bin/meteor:/usr/local/redis/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/Users/amills001c/golang/bin:/Users/amills001c/apache-maven-3.3.3/bin:/Users/amills001c/.rvm/bin
In OS X you would normally run the command like so:
open -a Terminal.app /path/to/script.sh
Which would open a new terminal window and execute your script.
Check the real name of the "terminal" command in your system, to check it, for example, in Ubuntu do "/usr/bin/env | grep terminal", in my case is "gnome-terminal", then use "gnome-terminal -e XXX" should work. Hope it helps J.
What worked for me was this:
var cp = require('child_process');
cp.spawn('sh', [ 'start-server.sh' ], {
detached: true,
env: {
NODE_ENV: process.env.NODE_ENV
}
});
#!/usr/bin/env bash (start-server.sh)
open "./run-node.sh"
#!/usr/bin/env bash (run-node.sh)
node ./bin/www.js
the open command will open the .sh file with the default app, which happens to be iterm2 for me, not terminal.app
the next problem I have is I have to pass paths as arguments to .sh files and I don't know how to do that yet
How can I run a shell script in a new cygwin window? The following just opens up the windows type of cmd window which is difficult to resize.
cygstart /cygdrive/c/cygwin/bin/bash ~/runmyapp.sh
Well, if you want to keep the window open after the script exits, you have to do something to make the shell that is executing the script not exit.
Here's an example that should work.
mintty bash -c "~/runfxtransact.sh; read -p \"Press enter to close this window.\"" &
I have to work on a project in Fedora Linux and I have to type the following very often:
player map1.cfg &
I figured out that I can create an executable .sh file and it contains this:
#!/bin/bash
player *.cfg &
However, when double click on the runmap.sh file it shows me 'Run in Terminal', 'Display', 'Cancel', and 'Run' and when I click 'Run in Terminal' a terminal window opens and closes immediately. If I just hit 'Run' then the .cfg opens but I need the Terminal window to run additional (Java) files.
How can I fix this problem?
Other information:
I use *.cfg because I want to copy and paste the .sh files into other folders that also contain .cfg files such as map2.cfg, map3.cfg, etc.
It's for a Player/Stage project.
When you run a script from the file manager, the shell that is started isn't interactive. The shell can only read the script file.
To open an interactive shell in addition to the files, you can exec the new shell at the end of the script, and use "Run in Terminal":
#!/bin/bash
player *.cfg &
exec /bin/bash
Well let's look at it this way.
When you run the command in a terminal, the command starts as a child process and is then sent to the background. Once the command finishes it terminates. During the time it is running in the background you can still issue commands because your parent process is the terminal window itself.
When you write a script that issues a command to run in the background it is started, spawns the command as a child to it and then closes because the script has finished.
These are a behavior of the OS and something that really shouldn't change. Essentially what you are therefore asking for is a way for it to run the command quickly for yourself yet still leave a command terminal for you to work with?
1) Why is typing the command such a hassle? Bash and other terminals have a history function for this very reason.
2) Why don't you just call the mini script you wrote from a terminal window whenever you need to call the commands. If you put the script in a folder on your $PATH variable it will be available to you in the terminal at any location.
I am not able to run gvim from cygwin. When I try to open a new file with :
gvim filename
gvim opens a file with 'No name' and displays error as :
Error detected while processing command line
E492: Not editor command: C:\cygwin\home\chandan\l
Press enter or type command to continue
More problematic is that I can't open existing file in the path
>which gvim shows /usr/bin/gvim
I have put alias gvim=/cygdrive/c/Program\Files\(x86\)/Vim/vim73/gvim.exe still
I wrote cyg-wrapper.sh for this sole purpose.
It supports:
symbolic links
options that must not be interpreted as pathnames (see -c with gvim, or any flags starting with a minus sign).
In other words, it enables us to type:
gvim /etc/profile -c /PS1 -c "echo 'correctly opened'"
# or even:
cd ~/tmp ; ln -s ~/bin/cyg-wrapper.sh
gvim -d http://hermitte.free.fr/cygwin/cyg-wrapper.sh cyg-wrapper.sh
explorer -e
explorer "$vim"
explorer http://hermitte.free.fr/
Note: I use the following function in my .profile to run gvim with cyg-wrapper.sh
gvim() {
opt=''
if [ `expr "$*" : '.*tex\>'` -gt 0 ] ; then
opt='--servername LATEX '
fi
cyg-wrapper.sh "C:/Progra~1/Edition/vim/vim73/gvim.exe" --binary-opt=-c,--cmd,-T,-t,--servername,--remote-send,--remote-expr --cyg-verbose --fork=2 $opt "$#"
}
EDIT: Currently (Sept 26 2014, using Vim 7.4), Windows gVim uses C:\Windows\gvim.bat to launch gVim from the command line. Replacing the gvim.exe path in the gvim() function with this script allows launching gvim without changing the path to match the current Vim version (which may actually be in Progra~2); however, it appears to also open a superfluous cmd.exe window.
Found this thread, I find the answer from jens unacceptable. We're not asking to be told not to do it. I didn't like the other answers either there was always some quirk, like settings not used or an extra command line window popping up. I Did some digging and this works for me. No extra command line box for nothing and it uses my proper gvim settings.
alias gvim='HOME=/cygdrive/p/ cygstart /cygdrive/c/Program\ Files\ \(x86\)/Vim/vim74/gvim.exe'
You simply need to alter the HOME to your own. To find out what to put there run gvim from windows then put in ":echo $HOME" and hit enter in my case it shows P:\ so that translates to /cygdrive/p/
Also if your gvim.exe is in a different directory/version you'll need to adjust.
Now when I type 'gvim script.sh' at a cygwin command prompt it launches gvim with the file, all nice and neat!
UPDATE
I found a slightly better way to do this. Using the alias was tying up my session that I ran the gvim from, I wanted it to launch as a separate process, using "gvim &" is inelegant as it lists job number when launching and displays a "done" line when completed. I'm too fussy so I figured out how to get that all tidy by using a function.
Just add this to your .bash_functions file, it builds on the previous section regarding home directory and backslash use.
gvim() {
ORIGHOME=$HOME
HOME=/cygdrive/p/
/cygdrive/c/Program\ Files\ \(x86\)/Vim/vim74/gvim.exe $1 & disown
HOME=$ORIGHOME
} 2>/dev/null
UPDATE 2 for babun users!
Ok since having wrestled with this originally I have ended up scrapping the original cygwin install in favor of babun which seems to be a less troublesome setup for those wanting linux functionality in windows without a full blown virtual. Of course my gvim launch script broke, and I had to do the following in my .zshrc file (babun uses zsh, at first I resisted and switched it to bash but then relented as I figured they must have reason, and they did, I like it)
gvim() {
OLD_HOME=$HOME
OLD_VIMRUNTIME=$VIMRUNTIME
export HOME=/cygdrive/c/Users/gmitchell/
export VIMRUNTIME="C:\Program Files (x86)\VIM\vim74"
TARGET=$(cygpath -w $1)
(/cygdrive/c/Program\ Files\ \(x86\)/Vim/vim74/gvim.exe $TARGET &)
export HOME=$OLD_HOME
export VIMRUNTIME=$OLD_VIMRUNTIME
}
*Note: the surrounding curved braces ( ) stops the job id from messing up your clean shell, and you no longer need the "disown"
P.S. The only remaining annoyance with this now is that you cannot "exit" the babun shell until all gvim instances you've launched are closed. Maybe someone can figure that own out. I've tried. When you type exit it just hangs there until you've exited all gvims.
Do yourself a favor, don't attempt to run a windows gvim from cygwin. The set of environment variables is likely completely different, and the pain of backslash directory separators, blanks in filenames, inability to understand /cygwin paths makes this an exercise in futility.
Then, what? Install the cygwin version of gvim and forget about all these problems.
Here is all you need to do:
alias gvim="run.exe /cygdrive/c/Programming/Tools/Vim/vim74/gvim.exe"
Works also with Notepad++, like so:
alias np="run.exe /cygdrive/c/Programming/Tools/Notepad++/notepad++.exe"
I have the same problem
because of the $SHELL var
so, I simple do like this
alias gvim='cmd /c "set SHELL=cmd & start gvim"'
It works for me, may be this will be help you too.
and maybe you want use the same alias for vim.
I put the following function in my .bashrc:
function gvim
{
GVIM_CMD=/cygdrive/c/path/to/gVimPortable.exe
if [[ -z "$1" ]]
then
$GVIM_CMD
else
$GVIM_CMD `cygpath -w $1`
fi
}
This allows me to launch gVim from anywhere.
It works fine for files with spaces, too...
This is a take off on low351's answer. I was unhappy with leaving HOME changed in the cygwin terminal, since I use that locally for a cygwin HOME, not my windows home. But gvim is all setup using Windows HOME. I added this to my .zshrc:
# run windows gvim from command line
gvim() {
local OLD_HOME=$HOME
HOME=/cygdrive/c/Users/jason/
local TARGET=$(cygpath -w $1)
/cygdrive/c/Program\ Files\ \(x86\)/Vim/vim74/gvim.exe $TARGET & disown
HOME=$OLD_HOME
} 2>/dev/null
really, just storing and restoring HOME. Being local, OLD_HOME goes away when the function returns, so it doesn't pollute the environment. If you're editing a cygwin file, running it through cygpath -w will make it a file path that windows gvim understands. It also lets you use window paths (e.g. C:/tmp/foo.txt) but w/ unix '/' separators, so you can dispense with /cygdrive/c. I believe this is all compatible w/ bash. This gives the following output:
> gvim
[2] 5060
>
It seems like the main problem is the HOME and VIM variables which are appropriate to the cygwin environment get exported when running Windows gvim, causing problems because Windows gvim knows nothing of cygwin. This fixes it:
alias gvim='env -u HOME -u VIM /cygdrive/c/Program\ Files\ \(x86\)/Vim/vim74/gvim.exe'
I have Windows gvim set as the default application (in Windows) for many filetypes, so Windows gvim frequently gets opened via the open alias. This fixes that use case:
alias open='env -u HOME -u VIM cygstart'
I just renamed gvim.bat which comes with the standard Win32 vim installation to gvim and put it into /usr/bin.
I am also sharing settings beetween Win32 GVim and Cygwin VIM referring to this article:
http://vim.wikia.com/wiki/Synchronize_configuration_to_many_computers
This way i can have both Vim and Win32 Gvim running with the same plugins and settings.
Since I've tried all of these and had issues I'll show what I'm using. I wrote it in ruby and it handles everything I throw at it (files, directories, or nothing) without any errors/popups/etc.
I saved it as gvim in ~/Dropbox/bin/cygwin/ (which is in my PATH)
#!/usr/bin/env ruby
args=''
filepath=''
arg=ARGV[0]
if arg
if File.exist? arg
if File.file? arg
args+="--remote-tab-silent "
end
filepath=`cygpath -w '#{arg}'`.strip
filepath="'#{filepath}'"
end
else
end
exe="'/c/Program\ Files\ \(x86\)/vim/vim73/gvim.exe' #{args} #{filepath}"
spawn exe
Here's the script I use for ~/bin/gvim. It runs it as if I called gvim FOO from the "Run" dialog (thanks to the batch file being invoked by explorer.exe). Can't play too nicely with the command line, but a self-deleting batch file comes to the rescue.
#!/bin/bash
TEMPFILE_NAME=gvim-`date +%s`-${RANDOM}.bat
TEMPFILE=$TMP/$TEMPFILE_NAME
TEMPFILE_W=`cygpath --windows --absolute --long-name "$TEMPFILE"`
TARGET=
if [ "$1" = "" ] ; then
TARGET=`cygpath --windows --absolute --long-name "."`
else
TARGET=`cygpath --windows --absolute --long-name "$#" | tr '\n' ' '`
fi
WIN_GVIM=`where gvim.exe | tr -d '\r\n'`
WIN_GVIM=`cygpath "$WIN_GVIM" --windows --absolute --long-name`
unix2dos > $TEMPFILE << EOF
start "gvim" "$WIN_GVIM" $TARGET
DEL %~f0
EOF
chmod +x $TEMPFILE
explorer.exe "$TEMPFILE_W"
Special thanks to this answer for the explorer.exe technique.
How can I open a new terminal from TCL code, do some operations (e.g. ls -l), get the results of those operations and close that terminal?
Does the exec command open a new terminal and all the operations are invoked in the terminal or when I call for example "cd .." with exec, that command has nothing to do with the linux terminal and linux commands, those are just pure tcl commands that have the same name as linux standard commands?
Sounds like you want Expect.
Any command you pass to exec will be sent to the system to be executed. exec does not open a terminal window to do this: it does not need to open a GUI window like a terminal just to interact with the underlying system.
A couple of specific notes about your example commands:
parsing the output of ls or ls -l is not recommended. Suppose you have an odd but valid filename like "foo\nbar". You're better off iterating over the results of Tcl's glob command.
cd happens to be a Tcl command.
I have done my task with this:
set cvsUpdStr [exec $pathToCvsInYourSystem -qn upd]
It does not open a terminal, but it does the task:
executes a command
results is being stored in cvsUpdStr and can be used later
Also it is possible to use it with catch to understand if it was executed correctly or to avoid errors:
if {[catch {exec $pathToCvsInYourSystem -qn upd} result]} {puts $result}