Alias command incorrectly executing - bash

I am attempting to load my git aliases from a gist on github. For some reason, the command executes find, but when I attempt to execute any of the aliases, they are either incorrectly mapped — e.g., gsts -> git stash instead of gsts -> git status — or they are not mapped at all.
#!/bin/bash
update_git_aliases(){
GIST_URL='https://gist.githubusercontent.com/Moyoka22/ec605b0b52fee6d6d30d5f72822938f4/raw/git-aliases'
RESPONSE="$(wget --no-cache -qO- ${GIST_URL})"
if [ ${?} -ne 0 ]
then
echo 'Download failed. Exiting.'
return 1
fi
echo ${RESPONSE} > ${1}
chmod +x ${1}
}
DOWNLOAD_FAILED=0
ALIAS_FILE="${HOME}/.config/git-aliases"
if [ ! -f ${ALIAS_FILE} ]
then
echo "Git aliases not found! Downloading..."
update_git_aliases ${ALIAS_FILE}
DOWNLOAD_FAILED=${?}
fi
if [ ${DOWNLOAD_FAILED} -ne 0 ]
then
echo "Downloading aliases failed."
exit 1
fi
cat ${ALIAS_FILE} | bash

I assume you want the aliases on your interactive shell, so remove the last cat as it's useless and once ${HOME}/.config/git-aliases is created
$ source "${HOME}/.config/git-aliases"

The alias commands must be run in your current shell process to have an effect.
cat ${ALIAS_FILE} | bash executes the alias commands in ALIAS_FILE in a new child process, not your shell, and not the program's shell.
source runs the commands in the current shell. You need to source the file from your current shell, not from the program. You can do this after the file is updated. In order to make this permanent, you will need to add source "${HOME}/.config/git-aliases" to your shell config.
What many programs like this do is print out the necessary commands at the end.
echo "$ALIAS_FILE updated"
echo "Make sure `source $ALIAS_FILE` is in your $HOME/.bash_profile"
echo "Run `source $ALIAS_FILE` to use it in your current shell"

Related

script file not found when using source

I have a bash script in a file named reach.sh.
This file is given exe rights using chmod 755 /Users/vb/Documents/util/bash/reach.sh.
I then created an alias using alias reach='/Users/vb/Documents/util/bash/reach.sh'
So far this works great.
It happens that I need to run this script in my current process, so theoretically I would need to add . or source before my script path.
So I now have alias reach='source /Users/vb/Documents/util/bash/reach.sh'
At this point when I run my alias reach, the script is failing.
Error /Users/vb/Documents/util/bash/reach.sh:7: = not found
Line 7 if [ "$1" == "cr" ] || [ "$1" == "c" ]; then
Full script
#!/bin/bash
# env
REACH_ROOT="/Users/vb/Documents/bitbucket/fork/self"
# process
if [ "$1" == "cr" ] || [ "$1" == "c" ]; then
echo -e "Redirection to subfolder"
cd ${REACH_ROOT}/src/cr
pwd
else
echo -e "Redirection to root folder"
cd ${REACH_ROOT}
pwd
fi
Any idea what I could be missing ?
I'm running my script in zsh which is not a bash shell, so when I force it to run in my current process it runs in a zsh shell and does not recognize bash commands anymore.
In your question, you say "It happens that I need to run this script in my current process", so I'm wondering why you are using source at all. Just run the script. Observe:
bash-script.sh
#!/bin/bash
if [ "$1" == "aaa" ]; then
echo "AAA"
fi
zsh-script.sh
#!/bin/zsh
echo "try a ..."
./bash-script.sh a
echo "try aaa ..."
./bash-script.sh aaa
echo "try b ..."
./bash-script.sh b
output from ./zsh-script.sh
try a ...
try aaa ...
AAA
try b ...
If, in zsh-script.sh, I put source in front of each ./bash-script.sh, I do get the behavior you described in your question.
But, if you just need to "run this script in my current process", well, then ... just run it.
source tries to read a file as lines to be interpreted by the current shell, which is zsh as you have said. But simply running it, causes the first line (the #!/bin/bash "shebang" line) to start a new shell that interprets the lines itself. That will totally resolve the use of bash syntax from within a zsh context.

Shell script to set environment variables

I wish to write a shell script to export variables.
Below I have listed the script .
echo "Perform Operation in su mode"
export ARCH=arm
echo "Export ARCH=arm Executed"
export PATH='/home/linux/Practise/linux-devkit/bin/:$PATH';
echo "Export path done"
export CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-';
echo "Export CROSS_COMPILE done"
But this doesn't seem to work properly. I have to individually execute the commands at the shell prompt instead.
You need to run the script as source or the shorthand .
source ./myscript.sh
or
. ./myscript.sh
This will run within the existing shell, ensuring any variables created or modified by the script will be available after the script completes.
Running the script just using the filename will execute the script in a separate subshell.
Please show us more parts of the script and tell us what commands you had to individually execute and want to simply.
Meanwhile you have to use double quotes not single quote to expand variables:
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"
Semicolons at the end of a single command are also unnecessary.
So far:
#!/bin/sh
echo "Perform Operation in su mode"
export ARCH=arm
echo "Export ARCH=arm Executed"
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"
echo "Export path done"
export CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-' ## What's next to -?
echo "Export CROSS_COMPILE done"
# continue your compilation commands here
...
For su you can run it with:
su -c 'sh /path/to/script.sh'
Note: The OP was not explicitly asking for steps on how to create export variables in an interactive shell using a shell script. He only asked his script to be assessed at most. He didn't mention details on how his script would be used. It could have been by using . or source from the interactive shell. It could have been a standalone scipt, or it could have been source'd from another script. Environment variables are not specific to interactive shells. This answer solved his problem.
Run the script as source= to run in debug mode as well.
source= ./myscript.sh
I cannot solve it with source ./myscript.sh. It says the source not found error.
Failed also when using . ./myscript.sh. It gives can't open myscript.sh.
So my option is put it in a text file to be called in the next script.
#!/bin/sh
echo "Perform Operation in su mode"
echo "ARCH=arm" >> environment.txt
echo "Export ARCH=arm Executed"
export PATH="/home/linux/Practise/linux-devkit/bin/:$PATH"
echo "Export path done"
export "CROSS_COMPILE='/home/linux/Practise/linux-devkit/bin/arm-arago-linux-gnueabi-' ## What's next to -?" >> environment.txt
echo "Export CROSS_COMPILE done"
# continue your compilation commands here
...
Tnen call it whenever is needed:
while read -r line; do
line=$(sed -e 's/[[:space:]]*$//' <<<${line})
var=`echo $line | cut -d '=' -f1`; test=$(echo $var)
if [ -z "$(test)" ];then eval export "$line";fi
done <environment.txt
In my case, I gave extra spaces before and after =.
For example, in my shell file(say deploy.sh)
I initially write
GIT_SHA = $(git rev-parse HEAD)
But I fixed it by using:
GIT_SHA=$(git rev-parse HEAD)
So please note that we should not give any spaces before and after the =.

Bash script to change parent shell directory [duplicate]

This question already has answers here:
Why can't I change directories using "cd" in a script?
(33 answers)
Closed 7 years ago.
What I'm trying to do
I've created a shell script that I've added to my $PATH that will download and get everything setup for a new Laravel project. I would like the script to end by changing my terminal directory into the new project folder.
From what I understand right now currently it's only changing the directory of the sub shell where the script is actually running. I can't seem to figure out how to do this. Any help is appreciated. Thank you!
#! /usr/bin/env bash
echo -e '\033[1;30m=========================================='
## check for a directory
if test -z "$1"; then
echo -e ' \033[0;31m✖ Please provide a directory name'
exit
fi
## check if directory already exist
if [ ! -d $1 ]; then
mkdir $1
else
echo -e ' \033[0;31m✖ The '"$1"' directory already exists'
exit
fi
# move to directory
cd $1
## Download Laravel
echo -e ' \033[0;32m+ \033[0mDownloading Laravel...'
curl -s -L https://github.com/laravel/laravel/zipball/master > laravel.zip
## Unzip, move, and clean up Laravel
echo -e ' \033[0;32m+ \033[0mUnzipping and cleaning up files...'
unzip -q laravel.zip
rm laravel.zip
cd *-laravel-*
mv * ..
cd ..
rm -R *-laravel-*
## Make the /storage directory writable
echo -e ' \033[0;32m+ \033[0mMaking /storage directory writable...'
chmod -R o+w storage
## Download and install the Generators
echo -e ' \033[0;32m+ \033[0mInstalling Generators...'
curl -s -L https://raw.github.com/JeffreyWay/Laravel-Generator/master/generate.php > application/tasks/generate.php
## Update the application key
echo -e ' \033[0;32m+ \033[0mUpdating Application Key...'
MD5=`date +”%N” | md5`
sed -ie 's/YourSecretKeyGoesHere!/'"$MD5"'/' application/config/application.php
rm application/config/application.phpe
## Create .gitignore and initial git if -git is passed
if [ "$2" == "-git" ]; then
echo -e ' \033[0;32m+ \033[0mInitiating git...'
touch .gitignore
curl -s -L https://raw.github.com/gist/4223565/be9f8e85f74a92c95e615ad1649c8d773e908036/.gitignore > .gitignore
# Create a local git repo
git init --quiet
git add * .gitignore
git commit -m 'Initial commit.' --quiet
fi
echo -e '\033[1;30m=========================================='
echo -e ' \033[0;32m✔ Laravel Setup Complete\033[0m'
## Change parent shell directory to new directory
## Currently it's only changing in the sub shell
filepath=`pwd`
cd "$filepath"
You can technically source your script to run it in your parent shell instead of spawning a subshell to run it. This way whatever changes you make to your current shell (including changing directories) persist.
source /path/to/my/script/script
or
. /path/to/my/script/script
But sourcing has its own dangers, use carefully.
(Peripherally related: how to use scripts to change directories)
Use a shell function to front-end your script
setup () {
# first, call your big script.
# (It could be open-coded here but that might be a bit ugly.)
# then finally...
cd someplace
}
Put the shell function in a shell startup file.
Child processes (including shells) cannot change current directory of parent process. Typical solution is using eval in the parent shell. In shell script echo commands you want to run by parent shell:
echo "cd $filepath"
In parent shell, you can kick the shell script with eval:
eval `sh foo.sh`
Note that all standard output will be executed as shell commands. Messages should output to standard error:
echo "Some messages" >&2
command ... >&2
This can't be done. Use exec to open a new shell in the appropriate directory, replacing the script interpreter.
exec bash
I suppose one possibility would be to make sure that the only output of your script is the path name you want to end up in, and then do:
cd `/path/to/my/script`
There's no way your script can directly affect the environment (including it's current directory) of its parent shell, but this would request that the parent shell itself change directories based on the output of the script...

Quick bash script to run a script in a specified folder?

I am attempting to write a bash script that changes directory and then runs an existing script in the new working directory.
This is what I have so far:
#!/bin/bash
cd /path/to/a/folder
./scriptname
scriptname is an executable file that exists in /path/to/a/folder - and (needless to say), I do have permission to run that script.
However, when I run this mind numbingly simple script (above), I get the response:
scriptname: No such file or directory
What am I missing?! the commands work as expected when entered at the CLI, so I am at a loss to explain the error message. How do I fix this?
Looking at your script makes me think that the script you want to launch a script which is locate in the initial directory. Since you change you directory before executing it won't work.
I suggest the following modified script:
#!/bin/bash
SCRIPT_DIR=$PWD
cd /path/to/a/folder
$SCRIPT_DIR/scriptname
cd /path/to/a/folder
pwd
ls
./scriptname
which'll show you what it thinks it's doing.
I usually have something like this in my useful script directory:
#!/bin/bash
# Provide usage information if not arguments were supplied
if [[ "$#" -le 0 ]]; then
echo "Usage: $0 <executable> [<argument>...]" >&2
exit 1
fi
# Get the executable by removing the last slash and anything before it
X="${1##*/}"
# Get the directory by removing the executable name
D="${1%$X}"
# Check if the directory exists
if [[ -d "$D" ]]; then
# If it does, cd into it
cd "$D"
else
if [[ "$D" ]]; then
# Complain if a directory was specified, but does not exist
echo "Directory '$D' does not exist" >&2
exit 1
fi
fi
# Check if the executable is, well, executable
if [[ -x "$X" ]]; then
# Run the executable in its directory with the supplied arguments
exec ./"$X" "${#:2}"
else
# Complain if the executable is not a valid
echo "Executable '$X' does not exist in '$D'" >&2
exit 1
fi
Usage:
$ cdexec
Usage: /home/archon/bin/cdexec <executable> [<argument>...]
$ cdexec /bin/ls ls
ls
$ cdexec /bin/xxx/ls ls
Directory '/bin/xxx/' does not exist
$ cdexec /ls ls
Executable 'ls' does not exist in '/'
One source of such error messages under those conditions is a broken symlink.
However, you say the script works when run from the command line. I would also check to see whether the directory is a symlink that's doing something other than what you expect.
Does it work if you call it in your script with the full path instead of using cd?
#!/bin/bash
/path/to/a/folder/scriptname
What about when called that way from the command line?

exiting script while running source scriptname over SSH

I have a script with a number of options in it one of the option sets is supposed to change the directory and then exit the script however running over ssh with the source to get it to change in the parent it exits SSH is there another way to do this so that it does not exit? my script is in the /usr/sbin directory.
You might try having the script run a subshell instead of whatever method it is using to “change [the directory] in the parent” (presumably you have the child print out a cd command and have the parent do something like eval "$(script --print-cd)"). So instead of (e.g.) a --print-cd option, add a --subshell option that starts a new instance of $SHELL.
d=/path/to/some/dir
#...
cd "$d"
#...
if test -n "$opt_print_cd"; then
sq_d="$(printf %s "$d" | sed -e "s/'/'\\\\''/g")"
printf "cd '%s'\n" "$sq_d"
elif test -n "$opt_subshell"; then
exec "$SHELL"
fi
If you can not edit the script itself, you can make a wrapper (assuming you have permission to create new, persistent files on the ‘server’):
#!/bin/sh
script='/path/to/script'
print_cd=
for a; do test "$a" = --print-cd && print_cd=yes && break; done
if test -n "$print_cd"; then
eval "$("$script" ${1+"$#"})" # use cd instead of eval if the script prints a bare dir path
exec "$SHELL"
else
exec $script" ${1+"$#"}
fi

Resources