I forked https://github.com/mathiasbynens/dotfiles dotfiles and tried to run bootstrap.sh which apparently should "pull in the latest version and copy the files to your home folder", according to the README.md
But when I try to source the bootstrap.sh, error returns. "bootstrap.sh:13 := not found". Line 13 is the doIt part in
if [ "$1" == "--force" -o "$1" == "-f" ]; then
doIt;
Does anybody have an idea where it went wrong? Thanks in advance.
#!/usr/bin/env bash
cd "$(dirname "${BASH_SOURCE}")";
git pull origin master;
function doIt() {
rsync --exclude ".git/" --exclude ".DS_Store" --exclude ".osx" \
--exclude "bootstrap.sh" --exclude "README.md" --exclude "LICENSE-MIT.txt" -avh --no-perms . ~;
source ~/.bash_profile;
}
if [ "$1" == "--force" -o "$1" == "-f" ]; then
doIt;
else
read -p "This may overwrite existing files in your home directory. Are you sure? (y/n) " -n 1;
echo "";
if [[ $REPLY =~ ^[Yy]$ ]]; then
doIt;
fi;
fi;
unset doIt;
It seems your shell has a problem with the == in the [ command.
The thing is, this operator is undocumented for this old command, so it's possible that some shells won't like it.
The command should work in a modern Bash, for example if you run the script this way:
bash bootstrap.sh
or this way:
./bootstrap.sh
Ideally, the script should not use obscure syntax, for example use this instead:
if [[ $1 == --force || $1 == -f ]]; then
Related
I call pylint in Container in Jenkins step
stage('Linting') {
sh "docker run -v $WORKSPACE:/workspace ${DOCKER_REGISTRY}/${DOCKER_TAG}:latest /workspace/lint.sh"
}
The problem is it only prints the result but never fails on Jenkins.
Here is bash file, 'lint.sh', to call pylint within the container:
#!/bin/bash
awd=$(pwd)
for file in $(find . -name '*.py'); do
filename=$(basename $file)
if [[ ${file:(-3)} == ".py" ]] && [[ $filename = *"test"* ]] ; then
echo "perform PEP8 lint (python pylint blah) for $filename"
cd $awd && cd $(dirname "${file}") && pylint "${filename}"
fi
done
Constraint: I must call docker and run the test because I'm using external Jenkins (Cloudbees) to get pip libraries.
Your script is still exiting with exit code 0 as written. If you want to quit immediately after a failed PyLint check, you can add an exit at the end of the check:
cd $awd && cd $(dirname "${file}") && pylint "${filename}" || exit 1
If you want to check all of the files, and track how many failed PyLint, you can do something like this:
#!/bin/bash
failed=0 # NEW
awd=$(pwd)
for file in $(find . -name '*.py'); do
filename=$(basename $file)
if [[ ${file:(-3)} == ".py" ]] && [[ $filename = *"test"* ]] ; then
echo "perform PEP8 lint (python pylint blah) for $filename"
cd $awd && cd $(dirname "${file}") && pylint "${filename}"
if [ $? -ne 0 ] ; then # NEW
failed=$(($failed + 1)) # NEW
fi # NEW
fi
done
exit $failed # NEW
I have the following script which works for the most part till it hits a specific line:
#!/usr/bin/env bash
set -eux
# Go Home.
cd /vagrant/Freya/
CLEANED_ASSETS=false
## Clean up time!
## Remove all vendor and composer.lock folders - just because.
for f in *; do
if [[ -d $f ]]; then
if [[ $f != ".git" ]] && [[ $f != "bin" ]] && [[ $f != "docs" ]]; then
if [[ $f == "Loader" ]] && [[ $CLEANED_ASSETS == false ]]; then
cd "$f/"
if [[ -d "Assets" ]]; then
cd Assets/
rm -rf vendor composer.lock docs
let $CLEANED_ASSETS=true
cd ../../
fi
fi
cd "$f/"
rm -rf vendor composer.lock docs
cd ../
fi
fi
done
The issue is when it hits let $CLEANED_ASSETS=true I am not sure the proper way to set this variable to true, so it never enters this loop again. I keep getting:
+ let false=true
bin/clean-directories: line 21: true: unbound variable
CLEANED_ASSETS=true
No let, no $.
In particular, the let causes true to be treated as a variable name (searched for a numeric value), and referring to variable names that don't exist gets you flagged by set -u.
I have no bash scripting knowledge unforunately. I need a script that reads a cd copied ONE file from the cd to a destination and renames it. Here is my code
#!/bin/bash
mount /dev/cd0 /mnt/
for file in /mnt/*
do
if($file == SO_CV*)
cp SO_CV* /usr/castle/np_new/CVFULLPC.BIN
else if($file == SO_PC*)
cp SO_PC* /usr/castle/np_new/PCMAP.BIN
else if($file == MS_PC*)
cp MS_PC* /usr/castle/np_new/FULLPC.BIN
else if($file == MS_MC*)
cp MS_MC* /usr/castle/np_new/MBFULLPC.BIN
done
umount /mnt/
Could someone tell me if this is even valid bash scripting, or what mistakes I might have made.
Thanks
Jim
Syntax problems. Try this code:
#!/bin/bash
mount /dev/cd0 /mnt/
for file in /mnt/*; do
if [[ "$file" == SO_CV* ]]; then
cp SO_CV* /usr/castle/np_new/CVFULLPC.BIN
elif [[ "$file" == SO_PC* ]]; then
cp SO_PC* /usr/castle/np_new/PCMAP.BIN
elif [[ "$file" == MS_PC* ]]; then
cp MS_PC* /usr/castle/np_new/FULLPC.BIN
elif [[ "$file" == MS_MC* ]]; then
cp MS_MC* /usr/castle/np_new/MBFULLPC.BIN
fi
done
umount /mnt/
an alternative:
#!/bin/bash
error_in_cp () {
{ printf "An ERROR occured while trying to copy: '\s' to its dest file.\n" "$#"
printf "Maybe there were more than 1 file ? or you didn't have the rights necessary to write the destination?"
printf "Exiting..."
} >&2 #to have it on STDERR
exit 1
}
mount /dev/cd0 /mnt/ &&
for file in /mnt/*; do
case "$file" in
SO_CV*) cp -p SO_CV* /usr/castle/np_new/CVFULLPC.BIN || error_in_cp "$file" ;;
SO_PC*) cp -p SO_PC* /usr/castle/np_new/PCMAP.BIN || error_in_cp "$file" ;;
MS_PC*) cp -p MS_PC* /usr/castle/np_new/FULLPC.BIN || error_in_cp "$file" ;;
MS_MC*) cp -p MS_MC* /usr/castle/np_new/MBFULLPC.BIN || error_in_cp "$file" ;;
*) echo "oops, forgot to handle that case: '$file' . ABORTING. "
exit 1
;;
esac
done # no "&&" here so you always umount /mnt/ even if you aborted the copy or the latest command went wrong
umount /mnt/
note: I changed the "cp" to "cp -p" to prevere rights & times... adjust if needed.
note that "&&" at the end of the line is ok
(no need to :
command && \
something
)
You may need to add { and } around each part if there is more than 1 element (here, "case ... esac" is one element, so it's fine)
I just think that it is convenient for me to "cd" to the directory where I store some file, ie.
[admin#local /]$ cd /usr/bin/somefile.pl
which as far as I know that the official "cd" command will not work.
so I wrote something like this:
main () {
if [[ "${1}" =~ "(.+/)*(.*){1}" ]] && [ -f "${1}" ] ; then
`\cd ${1%/*}`
elif [ -f "${1}" ] ; then
exit 0
else ; `\cd ${1}`
fi
}
main ${1}
and I alias this cd.sh to the "cd" command:
alias cd='source /somepath/cd.sh'
and this doesn't work.
I've tried to use eval "\cd xxx" instead of just \cd xxx;
How can I fix my script?
It feels like a bad idea to override cd, so I'll suggest a slightly different command, fcd:
fcd() { cd -- "$(dirname -- "$1")"; }
$ fcd /usr/bin/somefile.pl
$ pwd
/usr/bin
Or using parameter expansion to save a call to dirname:
fcd { cd -- "${1%/*}"; }
cd() {
DN="$(dirname "$1")"
if [[ -d "$1" ]]; then
builtin cd "$1"
elif [[ -d "$DN" ]]; then
builtin cd "$DN"
else
echo "$* or $DN: No such directories"
return 1
fi
return 0
}
I have a Bash function named "inDir" which abstracts the "go to a directory, do something, and come back to the starting directory" pattern. It is defined as:
inDir() {
if [ $# -gt 1 ]; then
local dir="$1"
local cwd=`pwd`
shift
if [ -d "$dir" ]; then
cd "$dir" && "$#"
cd "$cwd"
fi
fi
}
I am trying to create a function whose semantics don't matter much, but will essentially run:
inDir /tmp { [ -e testFile ] && touch testFile }
I hope the "implied" semantics are clear. I want to go into a directory, check if $somefile exists, and if it does, delete it. This is not working as intended. If I run:
cd
inDir /tmp [ -e testFile ] && touch testFile
it checks if testFile exists in /tmp, and then tries to touch it in ~. Can anybody think of a good way to invoke inDir so that it accepts "compound" commands?
indir() {
if [ -d "$1" ]; then
local dir="$1"
shift
(cd "$dir" && eval "$#")
fi
}
indir /tmp touch testFile
indir /tmp "[ -e testFile ] && rm testFile"
Nope. Just tell it to invoke a subshell.
inDir /tmp bash -c "[ -e testFile ] && touch testFile"