I have a lisp program that needs to run for a long, long time. I wanted to make a bash script so that I could just do $./script.sh& on my school's computer and then check the output periodically without having to be personally running the process. All I want to do is call the program "clisp" and have it execute these commands:
(load "ll.l")
(make)
and save all output to a file. How do I make this script?
Look at the nohup built-in bash command:
From Wikipedia
nohup is most often used to run
commands in the background as daemons.
Output that would normally go to the
terminal goes to a file called
nohup.out if it has not already been
redirected. This command is very
helpful when there is a need to run
numerous batch jobs which are
inter-dependent
You can launch the script with nohup, and when you relog see the progress in the nohup.out file
You just want something like this:
#!/bin/sh
clisp > OUTPUTFILE 2>&1 << EOF
(load "11.1")
(make)
EOF
Related
My bash script looks something like this
mpiexec ./fortran_bin |& tee text_file
wait
./process_output_files
My MPI-based Fortran program makes several synchronous system calls with call exec_cmd(cmd,wait=.true.).
My problem is that handle_output_files only waits for fortran_bin to finish, but some system commands (cmd) are not yet done, and this messes up my output files.
How do I make process_output_files wait for cmd to finish?
NOTES
I'm not sure where best to solve this problem (if there is a solution):
within Fortran, with MPI, within Bash ...
cmd is of the form cat out_{1..n} > out && rm -f out_{1..n}.
I would like it to run synchronously (wait=.false.), because cmd can be time-consuming, and unrelated to the rest of the Fortran program.
The wait line in the bash script seems to have no effect.
I suppose you could ask the equivalent question for a C/C++ program that calls system(some_script).
But I can only find question about waiting within a C/C++ program, if the same program needs the result of the called command (e.g., here and here).
From the notes above, looks like the sub command inherit the stdout/stderr on the calling process, and do not leave any background processes behind.
If those assumptions are true, you can impose a wait until there is no more output coming from the fortran_bin and it's children by piping the output into cat (or similar). The cat program will not terminate until all 'fortran_bin' children (that did not redirect stderr) will finish
mpiexec ./fortran_bin 2>&1 3>&1 | cat
Possible to use tee (or other similar programs) instead of cat
So, i'm running moses machine translation system on my server computer. I access terminal from ssh, and i came across an interesting problem.
The scrip i'm running uses > to specify and output file and it looks like this:
~/mosesdecoder/bin/moses -f /home/tin/working/filtered/moses.ini -i /home/tin/working/filtered/input.29242 > final
Now, since it will take some time for the translation to finish (around 10 hours) i want it to run with nohup, but when i do that even if i put & at the end i end up with file named "final" filled with stdout stuff.
Any idea on how to avoid it??
If you're running the commands inside an actual script file, you could get rid of the > inside the script, and run nohup ./sciptname.sh.
This will print the script's output to terminal, but nohup will redirect it to "nohup.out" in the current directory.
Source:
According to the nohup manpage I am reading, If the standard output is a terminal, the standard output is appended to the file nohup.out in the current directory.
Give it a shot :)
I have a Java program that I'm running using a Bash script on Mac OS X. I have two files - a FIFO that allows me to pipe commands into the program, and an output log file.
The Bash script consists of the following code:
#!/bin/bash
java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid
I honestly can't remember why I used >| in the third line (I just know that it works). In the java line, the first < redirects the fifo file to standard input. The >> should redirect standard output to the file, and the 2>&1 should redirect standard error to it as well. It then runs in the background.
The problem is that nothing is ever written to the server.log file. The command-fifo file is read, but the log is not written. The program IS writing to standard output (if I run it on its own it works fine).
I also tried script as suggested in this question but it didn't work either:
script -q /dev/null java -Xmx4G -Xms4G -jar current.jar --nogui <./run/command-fifo >>./run/server.log 2>&1 &
Anyone have ideas to get this to write to the log properly?
FOLLOWUP: I should explain a bit more of how the software works for this explanation to make sense. There are three parts at work here:
A plist that launchd uses to start the program at boot by calling the launcher script
A launcher script that handles kill signals and waits for the pid of the java process
A start script, called by the launcher script, that launches the program and saves its pid
The script given above is the start script. This launches the java process, echoes its pid to a file, then returns. The launcher script (not given here) then waits for the pid to exit before terminating. If it terminates, launchd automatically relaunches the launcher script.
Launchd has a feature that can set the standard output path for the file it launches. Essentially, it redirects stdout of the launcher script to the given file.
I did this, and lo and behold, it works. By changing the start script line to the following:
java -jar file.jar <>./run/command-fifo &
it allows standard output to be captured by launchd and written to the file. It's a bit different solution, but it does in fact work. It's strange because the launcher script technically has nothing to output since the java process is in the background, but however it works, it does i fact work somehow.
Of course, I'd prefer to explicitly redirect the file's standard output into a file (in other scripts there may be cases where there are more than one and I need to keep them separate). I'm still going to experiment and try to find a solution.
I think #torek's comment about buffering is probably right on the money. You can force your java process to line-buffer its output using the stdbuf utility:
#!/bin/bash
stdbuf -oL java -jar file.jar <./run/command-fifo >>./run/server.log 2>&1 &
echo $! >| ./run/server.pid
Regarding the >| operator, #torek is also correct. Here is the bash manual entry.
I am using a scheduler to run a unix script which starts up my application. The script is in the PATH of the user used by the scheduler. Hence, can be run from an y
My application log files are created relative to where the script is run from. Unfortunatley, the scheduler does not run the script from the folder I had hoped hence log files are not going to correct folder.
Is there any way in I get the script to run and behaves as it was run from a specified folder, e.g. ./ScriptName.sh Working_Folder | Run_Folder
Note: I cannot change the script
if your scheduler run your tasks using a shell (which it probably do) you can use { cd /log/dir ; script; } directly as command.
if not, you need to use a wrapper script as stated by #Gilles but i would do:
#!/bin/sh
cd /log/dir
exec /path/to/script "$#"
to save a little memory. The extra exec will make sure only the script interpreter is in memory instead of both (sh and the script interpreter).
If you can't change the script, you'll have to make the scheduler run a different command, not the script directly. For example, make the scheduler run a simple wrapper script.
#!/bin/sh
cd /desired/directory/for/log/files
/path/to/script "$#"
So, I have a Makefile which runs different commands of how to build S/W. I execute make from within a MSYS / MinGW enviroment.
I found for example, the sleep <seconds> command, but this only delays the execution. How can I make it wait for a key being pressed, for example?
You can use the read command. When you are done you press enter and your script/makefile continues. It's a builtin bash command, so it should work also on MinGW.
My proposition doesn't stop execution but halts and resume display on capable terminals:
Use ctrl-S for halting display, and ctrl-Q for resuming.
You don't need to modify your Makefile.
Pipe the output of the build through more (or less)
e.g.
make <make command line> | more
Or output everything to a file while still watching make progress on screen with your friend tee. I normally prefer this to less or more for bulkier projects.
make <make input arguments> 2>&1 | tee /some/path/build.log