Run in command line but gives error in shell script? - linux

I am new to Linux. I have a test system SuSe 64 bit. I have an executable file which I installed using a rpm file. The executable run fine when I ran through command line.
linux:linux_test>path/to/executable arg1 arg2
It ran successfully but when I put the same command in a shell script, it is throwing an error of No Such Directory or File
I checked the file type using file command and I got the following output:
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/LINUX 2.4.0, stripped
More Details:
command I am trying to execute is :
/opt/cds/scripts/EINJ /call del force where /opt/cds/scripts/EINJ is executable with path and /call del force are arguments passed
My shell script is contains following 2 lines :
#!/bin/bash
/opt/cds/scripts/EINJ /call del force
it gives me error :
/temp.sh: line2: /opt/cds/scripts/EINJ : No such file or directory
I also tried by changing the command to cd /opt/cds/scripts && ./ENIJ /call del force
Please help me how can I execute it from shell script.
Thanks in advance

I'm assuming you executed the file originally by way of a relative path, ./executable.sh. You must use the full path in your shell script or cd to the correct directory from within the script.
/path/to/executable.sh arg1 arg 2
or
cd /path/to
./executable.sh arg1 arg2
I suggest the first option, however you do have some other options:
Add the location of executable.sh to your $PATH.
Place executable.sh somewhere accessible from everywhere, namely /usr/local/bin.
Do not forget to set permissions for this file, which can be done with chmod +x executable.sh or chmod 0755 executable.sh.
Note that this will work for any executable files, not just .sh.

Related

Why i can excute a newly created file which is not executable?

In Ubuntu, The default umask on Ubuntu is 022 which means that newly created files are readable by everyone, but only writable by the owner, nobody can excute it.
In this case, i create a new file :
touch test.rb # Its content is: puts "hello world"
ls -l demo.rb # -rw-r--r--
Then i excute test.rb :
ruby test.rb # output: "hello world"
Since the owner of the file does not have the "x" permission , then why I can successfully run the file ? or I have missed some knowledge about it ?
You are not executing the file as a binary. You are executing ruby binary with argument test.rb and it interprets the Ruby script. Therefore, only ruby binary needs execution privilage and not the script itself.
You can check the privileges of the binary by running stat (which ruby).
On the other hand if you place
#!/usr/bin/ruby
on the top of your script and make it executable with chmod a+x test.rb you could then make Linux run it. The binfmt module of the kernel will check search for #! (called shebang) in the file and run the interpreter for you.
You can find this shebang in lot of the shell scripts. Nowadays it is common to put #!/usr/bin/env ruby or #!/usr/bin/env python in order to use interpreter binary in other location that is available on PATH variable like /usr/local/bin/ruby. Again env is just another binary program. It will run its argument as a program. The kernel will pass script as the parameter which will result in command /usr/bin/env ruby test.rb.
Grzegorz Żur is right.
you can modify your test.rb like this:
#!/usr/bin/env ruby
puts 'hello world'
and then you excute it with .:
$ ./test.rb
you will see Permission denied.

How to set a program to run in Linux terminal only with program name

I'm new to Linux and I wonder there are many programs we can use only program name to start it in Linux terminal, like gedit,vi,firefox instead of providing the all program's path,I like to run my own programs like this in terminal only typing program name, programs I like to run are written in Java and Python (.jar, .pyc, .py and .class)
I like to know how to do it with step by step
You can write whatever program/script you have to behave as a command. Let's say your executable script/program is named as my_script and is placed in /path/to/my_script.
Be sure that the script is executable. If not,then please do
chmod +x /path/to/my_script
Then, place a symlink to this location in /usr/local/bin as
sudo ln -s /path/to/my_script /usr/local/bin
You can add the symlink to any of the paths mentioned in $PATH.
That's it and enjoy your program.
The other answers all involve creating a symlink in a directory that is already listed in the system PATH, but I think it is more unixy to add needed directories to your PATH.
If your script is located at $HOME/bin/myscript and you have already made sure that it is executable then you can run
export PATH=$HOME/bin:$PATH
to run it without giving the full path. And you can add that same line to your .bashrc file in your home directory to have it preloaded whenever you start your shell. This approach does not require that the user has permission to create symlinks in system directories.
If you have an executable binary file in your home folder (let's say for example sublime_text) you must give it execute permision and call it with its relative path
chmod +x sublime_text
./sublime_text
If you made a symlink to it in /usr/bin (or other folders included in your PATH), you would be able to call it by its name
sudo ln -s ~/sublime_text /usr/bin/sublime_text
sublime_text
In your case, you aren't dealing with binary files, but with scripts meant to be interpreted. For this you must prepend a shebang telling linux what's the binary meant to execute the script. If it was, for example, a python script ~/hello.py, these could be the contents of the script:
#!/usr/bin/python
print "Hello, World!"
Where the first line tells linux to use the python binary to execute the script.
From then on, you can do:
chmod +x hello.py
sudo ln -s ~/hello.py /usr/bin/hello
hello
And it will echo "Hello World" to the console.

LD_LIBRARY_PATH fails in bash script

I have a bash script that runs this line of code:
LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib ./xattr infile.txt outfile.txt
If I were to call this line directly from the shell, it works fine. However if I run it in the bash script I get this error:
update.sh: line 45: LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib: No such file or directory
Why doesn't LD_LIBRARY_PATH work when it's set in a bash script?
Here's more of the code around line 45:
BASE_DIR="/volatile/huanlab/bold/kendal/bioinformatics_database/tmp"
COMP_DIR="$BASE_DIR/compound"
# move to the current directory where xattr.cpp and other files are
cd /users/kharland/software/programs/BioDB-update/dev
# Compile xattr ('make xattr' is the same command I call from the shell
# to compile this program when this program actually works).
make xattr
# loop over each .sdf file in COMP_DIR
for INF in $(ls $COMP_DIR | grep sdf)
do
babel -isdf $COMP_DIR/$INF -ocan $SMILES_DIR/$INF.csv
LD_LIBRARY_PATH=/tools/cluster/6.2/openbabel/2.3.2/lib ./xattr $COMP_DIR/$INF $COMP_DIR/$COMP_FILE
done
The contents before these lines are just comments
edit
In My makefile, I am compiling with these options
LDLIBS=-lm -ldl -lz -lopenbabel
LDFLAGS=-Wl,-rpath,/tools/cluster/6.2/openbabel/2.3.2/lib:/tools/cluster/system/pkg/openbabel/openbabel-2.3.2/build/lib,-L/tools/cluster/6.2/openbabel/2.3.2/lib
and running ldd xattr shows that the libraries are indeed linked, so the program executes as expected when invoked from the shell. The only issue is with the bash script. If I remove the LD_LIBRARY_PATH option from the bash script I get an issue where the shared libraries for openbabel aren't found even though ldd shows that xattr knows where the libs are. That's why I have LD_LIBRARY_PATH added in the bash script, I'm attempting to use it as a workaround
edit
(corrected mistake: swapped 'libraries' with 'my code' below)
(had wrong file system name below)
Something just occurred to me. My source code is in the /users file system. If my libraries are on a different, mounted file system, would bash have trouble finding these documents?
Setting environment variables does work in bash scripts.
Try this:
#!/bin/bash
VAR1=VALUE1 env
...run that script, and you'll see output that includes VAR1 and its value.
Generally speaking, this also works with LD_LIBRARY_PATH:
#!/bin/bash
tempdir=$(mktemp -t -d testdir.XXXXXX)
LD_LIBRARY_PATH=$tempdir env
rm -rf "$tempdir"
If you can generate a minimal reproducer in which this doesn't occur, that would be helpful and appreciated.

Modifying PATH in Linux

I recently installed linux, been trying to append stuff to my PATH but it doesn't seem to work. Here is my config file (~/.bashrc)
echo "Executing .bashrc ..."
export PATH=$PATH:/home/user/files/scripts
For example: i have a file "script_name.sh" in ~/scripts. I type "script_name" in a terminal and it gives an error: script_name: command not found. Am i missing something here?
try chmod +x myscript.sh
this will make the script executable.
On GNU/Linux (ie Unix), execution permission is require for execution.
(+x = make it executable)

TCL / TCLSH no such file or directory

I'm trying to build a software called Slicer3 on Windows 7 which features a "super build".
It's a All-in-one TCL Script to checkout and build Slicer3.
I ran CYGWIN and navigated til the correct directory, then ran the script and got:
$ ./Slicer3-svn/Scripts/getbuildtest.tcl
couldn't read file "./Slicer3-svn/Scripts/getbuildtest.tcl": no such file or directory
Obviously I am sure that the file exists and I gave it 777 permission. I'm running cygwin as admin.
The beginning of the tcl file's content is:
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$#"
So I tried commenting out line 3 and running directly
$ tclsh ./Slicer3-svn/Scripts/getbuildtest.tcl
but got the same error.
Any idea?
I will try to help troubleshooting as much as I can:
Determine if you have tclsh installed and it is in the PATH:
$ tclsh
Determine if tclsh works for a simple script:
$ echo puts hello > hello.tcl; tclsh hello.tcl
Determine if the script exists and readable:
$ cat ./Slicer3-svn/Scripts/getbuildtest.tcl
$ cd ./Slicer3-svn/Scripts
$ cat getbuildtest.tcl
As far as line-ending (DOS CRLF vs. Unix LF):
$ cd ./Slicer3-svn/Scripts
$ sed 's/\r\n/\n/g' getbuildtest.tcl > getbuildtest_new.tcl
$ tclsh getbuildtest_new.tcl
This way, we can narrow down the problem, should any of the steps failed.
Description: TCLSH couldn't read file: no such file or directory.
Possible reason: TCLSH under CYGWIN does not resolve windows PATH's properly, and cannot find the files.
Workaround: move the script within the CYGWIN path.
just moving the script to a "simpler" path works for me. I'm not that sure about the reason, neither how to solve this misbehaviour.

Resources