Very similar but not duplicate : https://stackoverflow.com/a/2172367/57883
I'm in Git Bash 3.1 (at least that's what comes up in the prompt when I type bash inside git bash.
and $ test [["DEV-0" == D*]] || echo 'fail' prints fail.
if [['DEV-0-1' == DEV* ]]; then echo "yes"; says [[DEV-0-1: command not found
I'm trying to test if git branch returns something that starts with DEV. but I can't seem to apply the answer. is it because all my attempts are using a string literal on the left instead of a variable value?
I've also tried it on ideone http://ideone.com/3IyEND
and no luck.
It's been ~14 years since I was good with a linux prompt.
What am I missing for a string starts with test in bash?
You missed a space there:
if [[ 'DEV-0-1' == DEV* ]]; then echo "yes"; fi
^^
I'd probably rather do the check like this:
s1=DEV-0-1
s2=DEV
if [ "${s1:0:${#s2}}" == "$s2" ]; then
echo "yes"
fi
Related
The code below tests if the character from a string is matching regex or not.
str=")Y"
c="${str:0:1}"
if [[ $c =~ [A-Za-z0-9_] ]]; then
echo "YES"
output=$c
else
echo "NO"
output="-"
fi
echo $output
I am running it with
source script-name.sh
However, instead of expected printout
NO
-
I am getting an empty line without dash
NO
I understand the issue is somehow around the way i (re-)assign output variable which being me to questions
How to do it properly?
Why source utility has such implication?
UPD_1: it is for Mac's zsh, not bash
UPD_2: the issue occurs only when running script via 'source' utility like "source script-name.sh"
Running with "./script-name.sh" yield correct result as well.
Your problem can be simplified to do on the zsh command line a
echo -
which also doesn't output anything. Similarily, a
echo - x
would output simply x and not - x.
This does not depend on whether or not you are on the Mac. If you would do a
echo - -
or a
=echo -
(the latter using the external program echo) would print a dash.
Therefore, you can change in your script-name.sh a
=echo $output
or a
echo - $output
and you should be fine.
The zshbuiltins man-page explains it, when describing the echo command:
the first dash, possibly following options, is not printed, but everything following it is printed as an argument.
Therefore, in zsh, at least when printing a variable, it is better to also use a lone dash for the safe side.
Your code gives the expected output for bash 4.2.46 on RHEL7.
Are you maybe using zsh?
See echo 'the character - (dash) in the unix command line
EDIT: Ok, if it's zsh, you probably have to use a hack:
if [[ ${output} == '-' ]]; then
echo - ${output}
else
echo ${output}
fi
or use printf:
printf $output"\n"
I'm trying to solve a very mundane problem. I want PS1 to change depending upon the previous command executed. Whether success or failure isn't the issue here. I want PS1 to include \w, but only if the last command entered was cd. What I have at the moment is:
if [[ !:0 == "cd" ]]
then
PS1='(\w)[jobs: \j] > '
else
PS1='[jobs: \j] > '
The output will always be the shorter one, regardless of the last command.
I feel like I'm making a simple mistake somewhere, and this also seems mundane enough that I can't find anything related through Google.
Put this in .bashrc:
PROMPT_COMMAND='
if [[ "$NEWPWD" != "$PWD" ]]; then
PS1="(\w)[jobs: \j] > "
NEWPWD=$PWD
else
PS1="[jobs: \j] > "
fi'
You can use whichever name you want for $NEWPWD
It's simple, it works, and is not prone to errors.
The Csh-style !:0 history expansion is an interactive feature. You can use the command history -p "!:0" to execute it in a script context, though (even when you have set +H, like most sane people have); but executing it inside PROMPT_COMMAND or the prompt itself is highly unwieldy. (When I tried, it would show me the penultimate command, or something from within the PROMPT_COMMAND scriptlet itself.)
Borrowing from https://stackoverflow.com/a/6110446/874188 (currently the accepted answer to Echoing the last command run in Bash?) I would go with
trap 'prompt_previous_command=$prompt_this_command; prompt_this_command=$BASH_COMMAND' DEBUG
PS1='$([[ ${prompt_previous_command%%\ *} == "cd" ]] && echo "(${PWD/$HOME/~})")[jobs: \j] \> '
It is unfortunate that echo "\\w" doesn't produce the expanded value in this context; ${PWD/$HOME/~} is a reasonable approximation, although there are corner cases where it gets it wrong.
... Perhaps a less confusing approach is to set the value in the trap already:
trap 'prompt_previous_command=$prompt_this_command
prompt_this_command=$BASH_COMMAND
[[ "${prompt_previous_command%%\ *}" == "cd" ]] &&
prompt_cwd="(\\w)" || prompt_cwd=""
PS1="$prompt_cwd[jobs: \\j] \\> "' DEBUG
Many Bash add-ons want to hook into your PROMPT_COMMAND and might sabotage any attempt to reserve it for youself; of course, this approach has a similar problem if you have something else in your system which relies on the DEBUG trap for something.
To make this work for pushd / popd and aliases etc too, here's an adaptation of Dan's excellent answer:
trap 'case ${prompt_prev_pwd-$PWD} in
"$PWD") PS1="[jobs \\j] > ";;
*) PS1="(\\w)[jobs: \\j] > ";;
esac
prompt_prev_pwd=$PWD' DEBUG
On approach is to create a function and parse history. The PROMPT_COMMAND is also needed.
Put the code below in your ~/.bashrc file or put it in another file, just make sure you source that file from ~/.bashrc
is_cd(){
set -- $(history 1)
if [[ $2 == "cd" ]]; then
echo cd_is_the_last_command
else
echo no_cd
fi
}
if [[ $PROMPT_COMMAND != *is_cd* ]]; then
PROMPT_COMMAND="is_cd"
fi
Change the lines with echo's with the actual command you want to execute.
Source ~/.bashrc after you have edited it.
This assumes that the output of your history has the numeric number first and command as the second column.
Hi I have written small shell script, I am not able to understand the behavior of that script. can any one help me to understand that script.
Script:
#!/bin/bash
if [ -z $1 ]
then
echo "fail"
else
echo "success"
fi
While executing the script .
./test.sh one
It exuting the else statement instead of main statement , even though its passing the argument.
can any one explain me this behavior to understand
The -z test in bash is checking if a string is an empty (zero length) value.
Since you're passing an argument to the script $1 is not empty and therefore -z $1 evaluates to false, executing the else portion of your script.
Side note: Since you're working with strings I recommend you to quote variables as follows:
if [ -z "$1" ]; then
echo "String is empty / No argument given"
else
echo "String is not empty / Argument given"
fi
Edit:
As pointed out by user1934428 it's probably better to use [[ instead of [. This, among others, eliminates the need for quoting. See more differences here.
if [[ -z $1 ]]; then
...
However, be aware that this is a bash extension and won't work in sh scripts.
I don't know bash well but this seems pretty basic, yet I'm stuck on it. I'm using the bash installed on Mac OS X. I'm simply trying to test 1 command line argument and this is what I have and it doesn't work.
if [$1 -eq 'clean']
then
echo "Your argument is 'clean'!"
fi
Every time I've tried it, bash gives me a command not found error.
I'm obviously doing something wrong, what is it?
Couple of issues here:
Spaces around [ and ] are required in shell
-eq is used for comparing integers not for strings
Try this instead:
if [[ "$1" == "clean" ]]; then
echo "Your argument is 'clean'!"
fi
If you are using bash then [[ and ]] are more efficient than [ and ]
is it possible to assign variable inside if conditional in bash 4? ie. in the function below I want to assign output of executing cmd to output and check whether it is an empty string - both inside test conditional. The function should output
"command returned: bar"
myfunc() {
local cmd="echo bar"
local output=
while [[ -z output=`$cmd` ]];
do
#cmd is failing so far, wait and try again
sleep 5
done
# great success
echo "command returned: $output"
}
why the above?
i prefer to run scripts with 'set -e' - which will cause script to terminate on first non-0 return/exit code that's not in an if/loop conditional.
with that in mind, imagine cmd is an unstable command that may exit with > 1 from time to time, and I want to keep calling it until it succeeds and i get some output.
You can try something like this:
myfunc() {
local cmd="echo bar"
local output=
while ! output=$($cmd) || [[ -z output ]];
do
#cmd is failing so far, wait and try again
sleep 5
done
# great success
echo "command returned: $output"
}
Note that it is strongly recommended to avoid the use of set -e.
I don't think you would be able to do it in your conditional
As yi_H pointed out, the if is equivalent to
if [[ ! -z output=bar ]];
which in turn is basically
if [[ ! -z "output=bar" ]];
So, all you are checking is if the string "output=bar" is empty or not...
So, output=bar could actually be anything like !##!#%=== and it would still do the same thing (that is, the expression isn't evaluated). You might have to assign the variable in a subshell somehow, but I'm not sure that would work.
Since assignment won't work there, you need some workaroudn.
You could temporary do a set +e...
You could use this way ...
$cmd
exit_status=$?
while [[ $exit_status -gt 0 ]];
do
#cmd is failing so far, wait and try again
sleep 5
$cmd
exit_status=$?
done
EDIT: This won't work with 'set -e' or other way around, don't use 'set -e' to begin with.