How to run my own programm using command in Shell? - shell

I just learned that I could use chmod make myscript.sh executable and the run it as $ ./myscript.sh But how can I attach a custom command to it, like $ connectme [options] ?

You need to do two things:
Give the name you want to use. Either just rename it, or establish a link (hard or symbolic). Make sure the correctly named object has the right permissions.
Make sure it is in you path. But putting "." in you PATH is a bad idea (tm), so copy it to $HOME/bin, and put that in you path.
A completely different approach. Most shells support aliases. You could define one to run your script.
Note: The environment variable PATH tells the shell where to look for programs to run (unless you specify a fully qualified path like /home/jdoe/scripts/myscript.sh or ./myscript.sh), it consists of a ":" seperated list of directories to examine. You can check yours with:
$ printenv PATH
resulting for me in
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/usr/X11R6/bin
which are the usual directories for binaries. You can add a new path element with (in /bin/sh and derivatives):
$ export PATH=$PATH:$HOME/bin
in csh and derivatives use
$ setenv PATH $PATH:$HOME/bin
either of which which will result in the shell also searching ~/bin for things to run. Then move your script into that directory (giving ta new name if you want). Check that you execute permissions for the script, and just type its name like any other command.
Fianlly, the use of a ".sh" extension to denote a shell script is for human consumption only. Unix does not care about how you name your script: it is the so-called "shebang" ("#!") on the first line of the script that the OS uses to find the interpreter.

You need to learn about arguments in BASH PROGRAMMING. Here is a good tutorial on them. Check section #4 out.
Basically, you need to use special variables $1, $2, $3 to refer to first, second and third command line arguments respectively.
Example:
$ ./mycript.sh A-Rod
With myscript.sh being:
#!/bin/bash
echo "Hello $1"
Will print:
Hello A-Rod

Related

How to set up a running environment on Ubuntu?

I want to customize a command to set up running environment, but I'm having some issue here. For example, I can run:
envsetup
and it will run the following script to help set up the environment:
cd /opt/dir/set_up | source environment
I have tried to add the following code to my $HOME .bashrc file, but it's not working (Maybe I should add it to the .bashrc in my root dir?):
alias envsetup = 'cd /opt/dir/set_up | source environment'
Could anyone let me know what might be wrong here please?
A couple of things:
The cd command changes directories and doesn't output anything to
standard output (stdout). So there's no point in piping its output to another command with |. If you want to execute two commands in sequence, you can separate with ;.
When defining an alias you can't be too generous
with spaces.
Here's an option, then, to do what I think you want:
alias envsetup='cd /opt/dir/set_up ; source environment'
Per additional desire expressed in the comment, if you want to come back to the original directory, you can do it this way:
alias envsetup='(cd /opt/dir/set_up ; source environment)'
This runs the commands in a subshell so your current shell setup is unchanged, including the current working directory.
Note that since this runs in a subshell, if source is intended to change the environment variables in a persistent way, then this will not work. You can, alternatively, try something like this:
alias envsetup='p=$(pwd) ; cd /opt/dir/set_up ; source environment ; cd $p'
This will run in the same shell. You can choose whatever name you wish for p.

How can I store and execute the command "export PATH=$PREFIX/bin" from a script?

I would like to write a script that has several commands of the kind
> export PATH=$PREFIX/bin
Where
> $PREFIX = /home/usr
or something else. Instead of typing it into the the Shell (/bin/bash) I would run the script to execute the commands.
Tried it with sh and then with a .py script having the line,
> commands.getstatusoutput('export PATH=$PREFIX/bin')
but these result into the error "bad variable name".
Would be thankful for some ideas!
If you need to adjust PATH (or any other environment variable) via a script after your .profile and equivalents have been run, you need to 'dot' or 'source' the file containing the script:
. file_setting_path
source file_setting_path
The . notation applies to all Bourne shell derivatives, and is standardized by POSIX. The source notation is used in C shell and has infected Bash completely unnecessarily.
Note that the file (file_setting_path) can be specified as a pathname, or if it lives in a directory listed on $PATH, it will be found. It only needs to be readable; it does not have to be executable.
The way the dot command works is that it reads the named file as part of the current shell environment, rather than executing it in a sub-shell like a normal script would be executed. Normally, the sub-shell sets its environment happily, but that doesn't affect the calling script.
The bad variable name is probably just a complaint that $PREFIX is undefined.
Usually a setting of PATH would look something like
export PATH=$PATH:/new/path/to/programs
so that you retain the old PATH but add something onto the end.
You are best off putting such things in your .bashrc so that they get run every time you log in.

Why does this script work in the current directory but fail when placed in the path?

I wish to replace my failing memory with a very small shell script.
#!/bin/sh
if ! [ –a $1.sav ]; then
mv $1 $1.sav
cp $1.sav $1
fi
nano $1
is intended to save the original version of a script. If the original has been preserved before, it skips the move-and-copy-back (and I use move-and-copy-back to preserve the original timestamp).
This works as intended if, after I make it executable with chmod I launch it from within the directory where I am editing, e.g. with
./safe.sh filename
However, when I move it into /usr/bin and then I try to run it in a different directory (without the leading ./) it fails with:
*-bash: /usr/bin/safe.sh: /bin/sh: bad interpreter: Text file busy*
My question is, when I move this script into the path (verified by echo $PATH) why does it then fail?
D'oh? Inquiring minds want to know how to make this work.
The . command is not normally used to run standalone scripts, and that seems to be what is confusing you. . is more typically used interactively to add new bindings to your environment (e.g. defining shell functions). It is also used to similar effect within scripts (e.g. to load a script "library").
Once you mark the script executable (per the comments on your question), you should be able to run it equally well from the current directory (e.g. ./safe.sh filename) or from wherever it is in the path (e.g. safe.sh filename).
You may want to remove .sh from the name, to fit with the usual conventions of command names.
BTW: I note that you mistakenly capitalize If in the script.
The error bad interpreter: Text file busy occurs if the script is open for write (see this SE question and this SF question). Make sure you don't have it open (e.g. in a editor) when attempting to run it.

Windows TYPE to Console recreated using Unix Shell scripting

We have simple Windows batch files that when an error occurs, an "ONCALL.bat" file is run to display support information that is maintained in a separate oncall.txt text file. This is our SOP.
ONCALL.BAT:
set scriptpath=%~dp0
TYPE "%scriptpath%oncall.txt"
I have zero experience with Unix and Shell scripts and I need to quickly provide a shell script equivalent to run in a Unix environment.
Could someone please provide me the .sh equivalent of this code?
Assuming that the help file and the script are in the same directory:
#!/bin/sh
SCRIPTPATH=`dirname "$0"`
cat "$SCRIPTPATH"/oncall.txt
$0 is the file path of the current script; the dirname command extracts the directory part of it. This way you can avoid using a hard-coded path for the help file within the script.
cat oncall.sh
#!/bin/bash
scriptpath=/path/to/scripts
cat ${scriptpath}/oncall.txt
After you create your file, it can't hurt to run
dos2unix oncall.sh
Just to be sure there are no windows Ctrl-M chars that will totally mystify you with the way they can screw up Unix script processing.
THEN
chmod 755 oncall.sh
To make the script executable.
confirm with
ls -l oncall.sh
You should see listing like
-rwxr-xr-x 1 userName grpname 5263 Nov 21 14:44 oncall.sh
Finally, call the script with a full or relative path, i.e.
./oncall.sh
OR
$PWD/oncall.sh
The first line is called the "shebang" line, and when your script is called, the OS reads the first line of the file, to find out what program to run to interpret the rest of the script file.
You may want/need to use as the first line "shebang" one of the following, but bash is a good guess
#!/bin/ksh
#!/bin/sh
#!/bin/ash
#!/bin/dash
#!/bin/zsh
OR you may worst case, your shell lives in a non-standard directory, then you'll have to spell that out, i.e.
#!/usr/bin/ksh
All shell support debugging arguments for trace and variable expansion like
#!/bin/ksh -vx
Or you can wrap just certain lines to turn debugginng on and off like
set -vx
cat ${scriptpath}/oncall.txt
set +vx
Given that
The ~dp special syntax between the % and the 0 basically says to expand the variable %0 to show the drive letter and path, which gives you the current directory containing the batch file!
I think /path/to/scripts is a reasonable substitute, scriptpath=$PWD would be a direct replacement, as there are no drive letters in Unix. The problem there, is that you either rely on unix PATH var to find your script or you cd /path/to/scripts and then run ./oncall.sh using the relative path./ to find the file without naving added a value to PATH.
IHTH.

In bash2, how do I find the name of a script being sourced?

Here's my situation:
I have multiple versions of a script in source code control where the name differs by a path name component (ex: scc/project/1.0/script and scc/project/1.1/script). In another directory, there is a symlink to one of these scripts. The symlink name is not related to the script name, and in some cases may change periodically. That symlink, in turn, is sourced by bash using the '.' command.
What I need to know: how do I determine the directory of the referenced script, on a 10 year-old system with Bash 2 and Perl 5.5? For various reasons, the system must be used, and it cannot be upgraded.
In Bash 3 or above, I use this:
dir=`perl -MCwd=realpath -MFile::Basename 'print dirname(realpath($ARGV[0]))' ${BASH_SOURCE[0]} $0`
Apologies for the Perl one-liner - this was originally a pure-Perl project with a very small amount of shell script glue.
I've been able to work around the fact that the ancient Perl I am using doesn't export "realpath" from Cwd, but unfortunately, Bash 2.03.01 doesn't provide BASH_SOURCE, or anything like it that I've been able to find. As a workaround, I'm providing the path information in a text file that I change manually when I switch branches, but I'd really like to make this figure out which branch I'm using on its own.
Update:
I apologize - apparently, the question as asked is not clear. I don't know in every case what the name of the symlink will be - that's what I'm trying to find out at run time. The script is occasionally executed via the symlink directly, but most often the link is the argument to a "." command running in another script.
Also, $0 is not set appropriately when the script is sourced via ".", which is the entire problem I'm trying to solve. I apologize for bluntness, but no solution that depends entirely upon $0 being set is correct. In the Perl one-liner, I use both BASH_SOURCE and $0 (BASH_SOURCE is only set when the script is sourced via ".", so the one-liner only uses $0 when it's not sourced).
Try using $0 instead of ${BASH_SOURCE[0]}. (No promises; I don't have a bash 2 around.)
$0 has the name of the program/script you are executing.
Is stat ok? something like
stat -c %N $file
bash's cd and pwd builtins have a -P option to resolve symlinks, so:
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
works with bash 2.03
I managed to get information about the porcess sourcing my script using this command:
ps -ef | grep $$
This is not perfect but tells your which is the to process invoking your script. It migth be possible with some formating to determine the exact source.

Resources