Incrementing Variables in Yaml pipeline - azure-devops

I am trying to increment a variable value by 1. Below is my code
variables:
a: 0
steps:
script: |
if [ $a == 0 ]; then
echo $a
$a=$a+1
fi
echo $a
but its not incrementing
I tried many types of incrementing formats, below are the list i tried,
((a+1))
a=$((a+=1))
let "a=a+1"
a=$((a + 1))
$[counter('$(a),1)]
a: $[counter(1)]
none of the above format is incrementing my variable.

Check the documentation: Define variables
In this case, your yaml may look like this:
variables:
a: 0
steps:
script: |
a = $(a)
if [ $a == 0 ]; then
echo $a
$a=$a+1
fi
echo $a
If you want to use an updated value in the next script task, you have to add
echo "##vso[task.setvariable variable=a;]"$a
Check Set variables in scripts

Related

Compare command substitution string not null in fish

I'm trying to test if a git repository has the showuntrackedfiles option set to no.
My first aproch was:
if test (git config --get status.showuntrackedfiles) = no
echo "hi"
else
echo "bye"
end
but this breaks if showuntrackedfiles is not set.
test: Missing argument at index 2
(Type 'help test' for related documentation)
bye
The only workaround I've found is:
if test (git config --get status.showuntrackedfiles; or echo "") = no
echo "hi"
else
echo "bye"
end
but it seems hacky. Is there a better way of approaching this?
No less hacky, but here's a way to see if a command substitution returned nothing:
set output (git config ...)
if test (count $output) -gt 0 -a $output = no; ...
Recall fish variables are lists, so count is checking if the list has more then zero elements.

How to get argument number i in shell script, where i is a variable

I'm trying to make a script which starts with the shebang #!/bin/sh, and which, amongst other things, loops through the script's arguments, in order to check whether a given argument is present.
Here's what I've come up with so far:
#!/bin/sh
mother_flag="n"
virgin_flag="n"
reset_flag="n"
i=0
while [ $i -le $# ]
do
echo "${i}" # <<< This line isn't doing what I want it to do!
if [ ${i} = "--mother" ]; then
mother_flag="y"
elif [ ${i} = "--virgin" ]; then
virgin_flag="y"
elif [ ${i} = "--reset" ]; then
reset_flag="y"
fi
i=$((i+1))
done
echo "mother_flag = $mother_flag"
echo "virgin_flag = $virgin_flag"
echo "reset_flag = $reset_flag"
This runs, but it doesn't do what I want it to do. If I run sh my_script --mother, ${i} gives 0 and then 1. What should I put to make ${?} (or its replacement) give my_script and then --mother? Or is this impossible in shell script?
Or is there a better way of checking through one's arguments in shell script?

How to define a function that either takes arguments or doesnt?

I am using Fish shell....
Basically, to do something like this:
if (first argument == --r) {
do something
} else {
Do something
if (first argument == --n) {
do more
}
}
To achieve the first if statement I tried:
if test (count $argv) -eq 1 -a $argv[1] = '--r'
But that gives a message:
test: Missing argument at index 6
Functions in Fish don't require their parameters to be specified when you define the function. Any arguments sent to the function by the user are automatically stored in an array called argv. In order to determine whether arguments were sent, you can either count the number of elements in the array, or determine the length of the array as a string. I do the latter:
function my_func
if [ -z "$argv" ]; # No arguments
echo "No arguments supplied"
return
else # At least one argument
if [ "$argv[1]" = "--r" ];
echo "Excellent!"
return
end
end
end
If you prefer to use count, then it will look more like this:
function my_func
if [ (count $argv) -eq 1 -a "$argv[1]" = "--r" ];
# Exactly one argument with specified value "--r"
echo "Excellent!"
return
else # May have arguments, but none equal to "--r"
echo "Give me the right arguments"
return
end
end
Your use of set -q argv[1] is also a good option. But when you're checking for string equality, don't forget to surround your variable in quotes, like this: test "$argv[1]" = "--r".
Here's another method, using the switch...case conditional test:
function my_func
# No arguments
if [ -z "$argv" ]; and return
# At least one argument
switch $argv[1];
case --r;
# do some stuff
return
case "*";
# Any other arguments passed
return
end
end
end
This worked for me:
if set -q argv[1] ;and test $argv[1] = "--r"
Let's start with the error you get when executing this:
if test (count $argv) -eq 1 -a $argv[1] = '--r'
That happens because fish first expands $argv[1] then executes test. If argv has no values then that statement turns into
if test 0 -eq 1 -a = '--r'
Which isn't valid syntax for the test command. It doesn't matter that the first sub-expression evaluates to false since test parses the entire expression before evaluating it.
Rather than doing test (count $argv) -eq 1 just do set -q argv[1] to test if argv has at least one argument. Note the lack of a dollar-sign.
If you're using fish 2.7.0 or newer I recommend the new argparse builtin for handling arguments. Several of the standard functions that ship with fish use it so you can look at them, as well as man argparse, for examples of how to use it. Using argparse is almost always safer, less likely to result in bugs due to sloppy argument parsing using hand written fish script, and will provide argument parsing semantics identical to most commands including all the fish builtins. Including correctly handling short and long flags.
well if the argument is optional then you can do this by:
//check if variable exists
if (typeof variable === 'undefined'){
}
else{
if(typeof variable){}
}

how to use * in sh string comparison

How to correctly use * in sh? I tried googling it but couldn't find anything. The following echo ture. why is that?
file="test test"
if [ "$file" != "te"* ]
then
echo true
else
echo false
fi
To avoid all the potential problems, when using POSIX shell, you should consider using the old expr regex or match expressions. Your choices are:
#!/bin/sh
file="test test"
if [ $(expr "$file" : "te.*") -gt 0 ]
then
echo true
else
echo false
fi
or
if [ $(expr substr "$file" 1 2) = "te" ]
then
echo true
else
echo false
fi
Not elegant, but they are the proper tools for the shell. A short explanation of each and the expr syntax for each is:
string : regularExp : returns the length of string if both sides match,
returns 0 otherwise
match string regularExp : same as the previous one
substr string start length : returns the substring of string starting from
start and consisting of length characters
I did a bit of googling and found a good bash scripting resource:
Advanced Bash-Scripting Guide
There is a segment that answers your question:
[[ $a == z* ]] # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).
[ $a == z* ] # File globbing and word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).
So in your case the condition should be:
if [[ file != te* ]]

comparison the content of a text and csv files

I need a sample bash script to compare a first line of a file(Result.txt) to first row and column of another file(table.csv), then send the result to an html file.
I am very basic in coding, this is what I found so far:
#!/bin/sh
Result.txt="$(head -n 1 < $1|tail -n 1)"
table.csv="$(head -n 1 < $2|tail -n 1)"
test "$R.txt" = "$sheet.csv" && (echo The same; exit 0)
Appreciate your help
Slightly tweaking your script.
#!/bin/bash
Res=$(head -n 1 "$1")
tab=$(head -n 1 "$2")
[[ $Res == $tab ]] && echo The same
Notes
"dot" is not a valid identifier (i.e. variable name) character: valid is letters, numbers and underscore, and the first character cannot be a number.
if you're doing head -1, there's no need to pipe that into tail -1
I think [[ is more readable than test, primarily because [[ forces you to have ]]
parentheses launch a subshell which is overkill for an echo statement.
the exit will only exit the subshell not your program
if you have multiple statements, use if ...; then ...; fi -- it's more readable.