How to properly write a bash executable file - bash

I am having some issue in writing a simple executable .sh file via bash.
The order of operation as soon as I open a terminal (ctrl+alt+T) are:
pc:~$ roscd
pc:~/catkin_docking_ws/devel$ cd ..
pc:~/catkin_docking_ws$ cd devel/lib/tuginterface/
pc:~/catkin_docking_ws/devel/lib/tuginterface$ ./tuginterface
I have been investigating this small issue and came across this source which advises to change and rename the project as an alias and that is exactly what I tried to do:
alias proj="roscd"
alias proj2="cd .."
alias proj3="cd devel/lib/tuginterface/"
alias exec="./tuginterface"
My current executable file after many trials is:
#!/bin/bash
alias proj="roscd"
alias proj2="cd .."
alias proj3="cd devel/lib/tuginterface/"
alias exec="./tuginterface"
But it still does not work.
The same post advises to create a script and after that an alias in the startup file.
Please advise on how to solve this problem and sorry if it is a simple question but I don't seem to catch the mistake I am making.

The script doesn't need to define aliases. Aliases are commands that you can type yourself. The script can just execute the commands directly.
#!/bin/bash
cd ~/catkin_docking_ws/devel/lib/tuginterface
./tuginterface
I've combined the three cd commands into one that jumps straight to the correct directory.
"But I thought cd doesn't work in shell scripts?"
It depends what you're looking for. When a script changes directory it affects later commands in the script, so in that respect it does work. The change of directory is only inside the script, though. The person calling the script won't see the directory change. Their current directory is unaffected.

Related

Bash alias causing error "bash: cd: too many arguments" only when set in .bashrc

I have several bash aliases set in my .bashrc but they generate errors every time I open a new terminal. Each time a new terminal opens, two bash: cd: too many arguments will appear. The aliases work as intended, but I would like to solve the errors anyway. Here are the aliases in question:
alias .1="cd .."
alias .2="cd ../.."
alias .3="cd ../../.."
alias .4="cd ../../../.."
alias .5="cd ../../../../.."
alias .=".1" #Trouble maker
alias ..=".2"
alias ...=".3"
alias ....=".4"
alias .....=".5"
I have narrowed it down to alias .=".1" as the culprit creating the errors. I understand the . is its own command and I am slapping an alias on top of it. I am not sure this is the issue or not, but I have noticed when I remove this line the errors disappear. Furthermore, running the alias on the CLI itself does not generate the same errors... only when in the .bashrc does it generate the errors.
Things I have tried:
Quotations on both sides of =
Changing alias .=".1" to alias .="cd .."
Adding a space before alias command in an attempt to suppress output
Aliasing . means you are changing how subsequent shell commands include other shell scripts. Since . and source do the same thing in bash you might be able to fix this by making sure that they're only using source. Look in .bash_profile for instance. Bash looks at a variety of files while it is starting and .bashrc is probably getting read by .bash_profile and something in there is trying to . some other file.
But really, why? Can you just add a dot to each of these and be ok with it? The .. directory is one level up so that could make it easier to remember. Changing things like this that are fundamental to how the shell operates and glues together multiple scripts is going to keep tripping you up.
The alias that is causing the error is: alias .=".1". The single period is a synonym for the source command, which reads in and executes commands from the file you pass as its argument.
What you're essentially doing (unintentionally), is trying to change the behavior of the source command using an alias.

Unix bash alias not working after start screen

Hi I am having a problem with setting alias in mac after I start the screen command, I have alias for working with git, like
commit=git commit
they work as I expect when I start my terminal (iTerm2), but then sometimes I use screen to have simultaneous instances in remotes servers and virtual machines I work with. After this the alias disappear(command not found).
Does anyone know why or how solve it?
To make the alias work, you must use the alias command. For example, to create an alias in Bash you do:
$ alias commit="git commit"
This works temporarily ie.: in your current shell. In order to make it "stick", you must put it in your ~/.bashrc. That will make it be sourced to all instances of Bash you'll invoke during your terminal session.
When you start screen, it starts a separate Bash too, so you'll be covered.
You write something about VMs. If you need this alias to work there, you must make ~/.bashrc on these VMs to have the same aliases. But that's the other story. You should already know how to achieve what you want.
You need to make sure your aliases are defined in ~/.bashrc to ensure they get included in all logins. You can test this out: edit your ~/.bashrc to include this line:
echo "bashrc"
And then edit your ~/.bash_profile to include this line:
echo "bash_profile"
You'll see when you start screen that only "bashrc" is displayed.
See this question for much more detail on the subject.

How to run a shell script just by typing its name?

I am very stuck on a task for my controlled assessment. I have been asked to create a shell script in nano that echoes hello world and hello $user. I have set the script to be executable. (chmod 755 Script1 and chmod +x Script1). I have been tasked to be able to make the script run just by typing 'Script1' , I do not know how to set the path to do this. Any help would be greatly appreciated.
Basically you need to have it in the PATH environment variable.
Suppose it's in a folder on /a/b/folder/script.sh, try:
PATH=$PATH:/a/b/folder/
This tells the shell to look for executables there when looking for commands to run.
To make sure it's always executable you have several options:
Set the path variable in your profile using ~/.bashrc (sets it for bash, commonly done in ubuntu, which is what I use) or ~/.profile.
Set it globally using /etc/environment or others...
Move the folder to a folder already on your path (echo $PATH to see what's there already).
Note that these files are source-ed on different stages and persist on different environments.
For even more information read this.
TIP: To test that you've set the file correctly, we'll take ~/.bashrc as an example, you can use source ~/.bashrc and everything in ~/.bashrc will be loaded. That way you can be sure it won't mess things up next time you log in.
Alias the script in .bash_profile
in home path open the .bash_profile file and add the following entry,
alias Script1='/path/to/Script1'
Then reload the bash by,
. .bash_profile
After that try to call the script by using just its name. i.e, Script1

Creating aliases in .bash_profile that run a shell script

So I have a script called spotlyrics.sh that I want to be able to run using the command "lyrics" in the terminal.
I have opened up my .bash_profile and am wondering how I can create the alis which 1) finds the script and then 2) executes it
The file is inside a folder called bash at the following path
/Users/username/Documents/bash
What I have so far (inside my bash profile), which doesn't work because I guess it's not "executing" the script.
alias spotlyrics=“/Users/username/Documents/bash/spotlyrics.sh“
I get the following error when running "spotlyrics" in the terminal:
-bash: “/Users/username/Documents/bash/spotlyrics.sh“: No such file or directory
Would love some help, thanks!
You've been editing your .bash_profile with something that is not a proper text editor. The quotation marks are not ASCII, and therefore not actually quotation marks as far as the shell is concerned.
Instead of beating around the bush with aliasing a script to a name it mostly already has, why not put the script in a directory in PATH and let it be its own command?
mkdir ~/bin
echo 'PATH+=:$HOME/bin' >> ~/.bashrc
mv "/path/to/spotlyrics.sh" ~/bin/spotlyrics && chmod +x ~/bin/spotlyrics
Then restart the shell (log out and back in) and you won't need the alias.
Well, the shell scripts are not executable by just calling it's name, they should be run using "source" command(in case of not c-shell, dot command(.) can also be used).So while adding an alias in .bashrc or .bash_profile for running a shell script append source command before the path to the shell script.
In your case probably this should work:`
alias spotlyrics='source /Users/username/Documents/bash/spotlyrics.sh'`
Please let me know if it doesn't work. Because it worked for me.

How do I execute a bash script in Terminal?

I have a bash script like:
#!/bin/bash
echo Hello world!
How do I execute this in Terminal?
Yet another way to execute it (this time without setting execute permissions):
bash /path/to/scriptname
$prompt: /path/to/script and hit enter. Note you need to make sure the script has execute permissions.
cd to the directory that contains the script, or put it in a bin folder that is in your $PATH
then type
./scriptname.sh
if in the same directory or
scriptname.sh
if it's in the bin folder.
You could do:
sh scriptname.sh
This is an old thread, but I happened across it and I'm surprised nobody has put up a complete answer yet. So here goes...
The Executing a Command Line Script Tutorial!
Q: How do I execute this in Terminal?
The answer is below, but first ... if you are asking this question, here are a few other tidbits to help you on your way:
Confusions and Conflicts:
The Path
Understanding The Path (added by tripleee for completeness) is important. The "path" sounds like a Zen-like hacker koan or something, but it is simply a list of directories (folders) that are searched automatically when an unknown command is typed in at the command prompt. Some commands, like ls may be built-in's, but most commands are actually separate small programs. (This is where the "Zen of Unix" comes in ... "(i) Make each program do one thing well.")
Extensions
Unlike the old DOS command prompts that a lot of people remember, you do not need an 'extension' (like .sh or .py or anything else), but it helps to keep track of things. It is really only there for humans to use as a reference and most command lines and programs will not care in the least. It won't hurt. If the script name contains an extension, however, you must use it. It is part of the filename.
Changing directories
You do not need to be in any certain directory at all for any reason. But if the directory is not on the path (type echo $PATH to see), then you must include it. If you want to run a script from the current directory, use ./ before it. This ./ thing means 'here in the current directory.'
Typing the program name
You do not need to type out the name of the program that runs the file (BASH or Python or whatever) unless you want to. It won't hurt, but there are a few times when you may get slightly different results.
SUDO
You do not need sudo to do any of this. This command is reserved for running commands as another user or a 'root' (administrator) user. Running scripts with sudo allows much greater danger of screwing things up. So if you don't know the exact reason for using sudo, don't use it. Great post here.
Script location ...
A good place to put your scripts is in your ~/bin folder.
You can get there by typing
# A good place to put your scripts is in your ~/bin folder.
> cd ~/bin # or cd $HOME/bin
> ls -l
You will see a listing with owners and permissions. You will notice that you 'own' all of the files in this directory. You have full control over this directory and nobody else can easily modify it.
If it does not exist, you can create one:
> mkdir -p ~/bin && cd ~/bin
> pwd
/Users/Userxxxx/bin
A: To "execute this script" from the terminal on a Unix/Linux type system, you have to do three things:
1. Tell the system the location of the script. (pick one)
# type the name of the script with the full path
> /path/to/script.sh
# execute the script from the directory it is in
> ./script.sh
# place the script in a directory that is on the PATH
> script.sh
# ... to see the list of directories in the path, use:
> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ... or for a list that is easier to read:
> echo -e ${PATH//:/\\n}
# or
> printf "%b" "${PATH//:/\\n}"
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
2. Tell the system that the script has permission to execute. (pick one)
# set the 'execute' permissions on the script
> chmod +x /path/to/script.sh
# using specific permissions instead
# FYI, this makes these scripts inaccessible by ANYONE but an administrator
> chmod 700 /path/to/script.sh
# set all files in your script directory to execute permissions
> chmod +x ~/bin/*
There is a great discussion of permissions with a cool chart here.
3. Tell the system the type of script. (pick one)
Type the name of the program before the script. (Note: when using this method, the execute(chmod thing above) is not required
> bash /path/to/script.sh
...
> php /path/to/script.php
...
> python3 /path/to/script.py
...
Use a shebang, which I see you have (#!/bin/bash) in your example. If you have that as the first line of your script, the system will use that program to execute the script. No need for typing programs or using extensions.
Use a "portable" shebang. You can also have the system choose the version of the program that is first in the PATH by using #!/usr/bin/env followed by the program name (e.g. #!/usr/bin/env bash or #!/usr/bin/env python3). There are pros and cons as thoroughly discussed here.
Note: This "portable" shebang may not be as portable as it seems. As with anything over 50 years old and steeped in numerous options that never work out quite the way you expect them ... there is a heated debate. The most recent one I saw that is actually quite different from most ideas is the "portable" perl-bang:
#!/bin/sh
exec perl -x "$0" "$#"
#!perl
Firstly you have to make it executable using: chmod +x name_of_your_file_script.
After you made it executable, you can run it using ./same_name_of_your_file_script
Change your directory to where script is located by using cd command
Then type
bash program-name.sh
And yet one more way
. /path/to/script
What is the meaning of the dot?
If you are in a directory or folder where the script file is available then simply change the file permission in executable mode by doing
chmod +x your_filename.sh
After that you will run the script by using the following command.
$ sudo ./your_filename.sh
Above the "." represent the current directory.
Note!
If you are not in the directory where the bash script file is present then you change the directory where the file is located by using
cd Directory_name/write the complete path
command. Otherwise your script can not run.

Resources