I have read other threads enter link description herethat discuss .bat to L/unix conversions, but none has been satisfactory. I have also tried a lot of hack type approach in writing my own scripts.
I have the following example.bat script that is representative of the kind of script I want to run on unix.
Code:
echo "Example.bat"
perl script1 param.in newParam.in
perl script2 newParam.in stuff.D2D stuff.D2C
program.exe stuff.D2C
perl script3 stuff.DIS results.out
My problem is I don't know how to handle the perl and program.exe in the unix bash shell. I have tried putting them in a system(), but that did not work. Can someone please help me?
Thank you!
Provided that you have an executable file named program.exe somewhere in your $PATH (which you well might — Unix executables don't have to end in .exe, but nothing says they can't), the code you've pasted is a valid shell script. If you save it in a file named, say, example.bat, you can run it by typing
sh example.bat
into the shell prompt.
Of course, Unix shell scripts are usually given the suffix .sh — or no suffix at all — rather than .bat. Also, if you want your script to be executable directly, by typing just
example.sh
rather than sh example.sh, you need to do three things:
Start the script with a "shebang" line: a line that begins with #! and the full path to the shell interpreter you want to use to run it (e.g. /bin/sh for the basic Bourne shell), like this:
#!/bin/sh
echo "This is a shell script."
# ... more commands here ...
Mark your script as executable using the chmod command, e.g.
chmod a+rx example.sh
Put your script somewhere along your $PATH. On Unix, the default path will not normally contain the current directory ., so you can't execute programs from the current directory just by typing their name. You can, however, run them by specifying an explicit path, e.g.
./example.sh # runs example.sh from the current directory
To find out what your $PATH is, just type echo $PATH into the shell.
Related
. ~/.bashrc is what I'm use to source the bash script in bash shell. But I have quite a few scripts that I want to run from tcsh.But this command doesn't work for tcsh. Why doesn't this work? Is there a different file similar to bash profile when I work on t shell?
Any links to look up?
Thx!
The tcsh equivalent to the bash and posix shell . is source.
That said, bash and tcsh are entirely different shells. You will not be able to source ~/.bashrc from tcsh, if that was your intent.
You can run a shell script of any type as long as that shell script has the appropriate shebang in its first line, but it'll run in its own process, and not in the context of your interactive tcsh instance.
If, for example, you have a directory: ~/.tcshrc.d, and you want to include all the files in that directory in your login shell, you might include the following in your .tcshrc file:
foreach i ( ~/.tcshrc.d/* )
source $i
end
Note that this is tcsh code, and is not compatible with bash.
They handle executable elfs, scripts and symbolic links from PATH, however what the algorithm of this doing? I'm afraid of I cannot find a source code of this part of a shell.
UDP: Oh, I'm stupid. It looks for EACH executable file in PATH, either directory or ordinary file.
Well, the actual search is performed by find_user_command_in_path() in findcmd.c:553.
The algorithm to search for a command ${foo} is basically:
check if ${foo} is absolute: if it is return this path and stop searching
iterate over all elements in PATH: for p in ${PATH}
construct a path ${p}/${foo} and see if it exists
if it exists and is executable return this path and stop searching
I'm no expert in this area, but I'm almost perfectly sure that on Linux the executable bit in file permissions is all that matters. No sophisticated algorithm needed.
Let's say that we have a file called hello in the current directory, and that the file contains just one line: echo "hello"
If you ran chmod 755 on the file and and you subsequently execute the file, then the bash shell will look through every path that you have listed in the PATH variable of say .bashrc, starting with the first path, until it locates the first path that contains your hello executable. Think of PATH as a linked list and think of the bash shell as going through the linked list of paths, path by path. If the bash shell is not running the hello executable that you want it to run, you have one option: put your hello executable in any one of the preceeding paths.
I am lazy. I don't bother to turn hello into an executable i.e. I am not running the chmod command and I just run
bash hello
where the bash shell is going to look for the hello file in the current directory, fork a bash process and the forked bash process is going to run the hello file before the forked bash process dies.
I am using the bash shell as an example but any other shell will behave the same way.
I tried to create a script in linux, on a Synology server over SSH
so I wrote a file test.sh
#!/bin/bash
echo "this is a test"
I saved the file.
after that I did
chmod 755 test.sh
the I did
./test.sh
then i got this error
-ash "./test.sh" is not found
the file was created in
/root
I don't understand
Your shell (ash?) is trying to execute your script and is getting an ENOENT (no such file or directory) error code back. This can refer to the script itself, but in this case it refers to the interpreter named in the #! line.
That is, /bin/bash does not exist and that's why the script couldn't be started.
Workaround: Install bash or (if you don't need any bash specific features) change the first line to #!/bin/sh.
This is one of the quirks with hash bang programs. If the interpreter is not found (i.e. the program interpreting the script), you don't get a completely useful error like /bin/bash: no such file, but a completely useless and misleading test.sh: not found.
If this isn't in the Unix Hater's Handbook, it should be. :-)
You can either use #!/bin/sh or #!/path/to/bash or #!/usr/bin/env bash (which searches PATH for bash).
This is a pretty simple one... I just want to make a perl script executable without the preceding perl command, and instead let the environment deduce the interpreter from the shebang line. Here is my sample script called test:
#!/usr/bin/perl
print "Hey there\n";
I then use chmod 775 test to make the script executable. If I use the command perl test, I get the output Hey there.
However, if I just type test, I get no output. What's the deal? Why isn't my shebang line making the environment realize this is perl? Can someone please help me?
Don't name your script test. This is a built-in command in most shells, so they don't go looking for an external program.
Also, to run a program in your current directory, you should type ./programname. It's generally a bad idea to have . in your $PATH, which would be necessary to execute it without the directory prefix.
To run something from the current directory you need to prefix "./" to tell it "this directory" ie ./testprogram.
If you type just test it will look in standard install directories like /bin. This is why when you run cp or rm it knows where the executable is.
As mentioned by others, naming scripts test is not allowed with most shells.
i want to run a program via script.
normally i type ./program in the shell and the program starts.
my script looks like this:
#!/bin/sh
cd /home/user/path_to_the_program/
sh program
it fails, i think the last line went wrong...
i know this is childish question but thx a lot!
If ./program works in the shell, why not use it in your script?
#!/bin/sh
cd /home/user/path_to_the_program/
./program
sh program launches sh to try and interpret program as a shell script. Most likely it's not a script but some other executable file, which is why it fails.
When you type
./program
The shell tries to execute the program according to how it determines the file needs to be executed. If it is a binary, it will attempt to execute the entry subroutine. If the shell detects it is a script, e.g through the use of
#!/bin/sh
or
#!/bin/awk
or more generally
#!/path/to/interpreter
the shell will pass the file (and any supplied arguments) as arguments to the supplied interpreter, which will then execute the script. If the interpreter given in the path does not exist, the shell will error, and if no interpreter line is found, the shell will assume the supplied script is to executed by itself.
A command
sh program
is equivalent to
./program
when the first line of program contains
#!/bin/sh
assuming that /bin/sh is the sh in your path (it could be /system/bin/sh, for example). Passing a binary to sh will cause sh to treat it as a shell script, which it is not, and binary is not interpretable shell (which is plain text). That is why you cannot use
sh program
in this context. It will also fail due to program being ruby, awk, sed, or anything else that is not a shell script.
You don't need the sh and looks like you don't have the path to the program in your $PATH.
Try this:
#!/bin/sh
cd /home/user/path_to_the_program/
./program
You don't need the "sh" here. Just put "program" on the last line by itself.
This should be enough:
/home/user/path_to_the_program/program
If that does not work, check the following:
executable bit
shebang line of the program (if it is a script)