Escaping bash code sequence inside a powershell script - linux

I need to connect from PowerShell to a Linux machine, get some folders that match a name and afterwards delete them (if you're asking why, cleanup for a test environment).
To accomplish this, I'm using the SSH.NET library (details here) and my script looks like this so far:
New-SshSession -ComputerName UbuntuMachine -Username root -Password test1234
Invoke-SshCommand -InvokeOnAll -Command {\
cd /dev;\
shopt -s nullglob;\
backupsToDelete=(Nostalgia*);\
printf "%s\n" "${backupsToDelete[#]}";\
for i in "${backupsToDelete[#]}"\
do\
printf $i\
done}
Everything works fine until I reach the point where I need to loop through my backupsToDelete array. It seems that for some reason, PowerShell is treating the for loop as it's own statement and not a bash one, everything resulting in an error:
At C:\Users\Administrator\Desktop\CleanupLinux.ps1:7 char:6
+ for i in "${backupsToDelete[#]}"\
+ ~
Missing opening '(' after keyword 'for'.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingOpenParenthesisAfterKeyword
Is there any way to tell PowerShell to not execute these kind of statements as it's own? Or maybe a different approach?

$command = "#
{\
cd /dev;\
shopt -s nullglob;\
backupsToDelete=(Nostalgia*);\
printf "%s\n" "${backupsToDelete[#]}";\
for i in "${backupsToDelete[#]}"\
do\
printf $i\
done}
#"
New-SshSession -ComputerName UbuntuMachine -Username root -Password test1234
Invoke-SshCommand -InvokeOnAll -Command $command
try like so.

Related

Changes required in my shell script in Linux

following is the script:
#!/bin/bash
declare pspath=""
declare user=""
declare password=""
declare password=""
for i in "$#"; do
case $i in
--pspath=*)
pspath="${i#*=}"
shift
;;
--user=*)
user="${i#*=}"
shift
;;
--password=*)
password="${i#*=}"
shift
;;
esac
--ip=*)
ip="${i#*=}"
shift
;;
esac
done
command="$pspath -username $user -password $password -ip $ip
$t="sudo pwsh -Command "$command""
echo $t
command i'm running:
./test.sh --pspath=test.ps1 --user=test --password=test$123 --ip=0.0.0.0
output coming:
sudo pwsh -Command test.ps1 -username test -password test23 -ip 0.0.0.0
expected output:
sudo pwsh -Command test.ps1 -username 'test' -password 'test$123' -ip 0.0.0.0
can anyone help me here, please?
PS: command cannot be changed, so need to make changes in shell script itself.
Thanks in Advance
You wrote
./test.sh --pspath=test.ps1 --user=test --password=test$123 --ip=0.0.0.0
You wanted
./test.sh --pspath=test.ps1 --user=test --password='test$123' --ip=0.0.0.0
As written, you are passing in this password:
./test.sh --pspath=test.ps1 --user=test --password=test23 --ip=0.0.0.0
Once you've done that, the $1 characters are lost forever
and cannot be reconstructed by the test.sh script.

Return value from LinuxVM to Azure Pipeline

The Linux VM is created using the Azure Pipeline. There is one folder which is created dynamically within the /data/config folder. The requirement is to return the name of this folder to the DevOps Pipeline.
The powershell code to invoke the shell script is as below
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VirtualMachineName -CommandId RunShellScript -ScriptPath "$($PSScriptRoot)/scripts/$PatchScript" -Parameter #{InputConf=$ReplInputConf}
I have done the following in the shell script and the folder name is written to a.txt
sudo -u $User find /data/config -maxdepth 1 -type d | sed 's/.*\///' >> /log/a.txt
sudo -u $User sed -i "/^\s*$/d" /log/a.txt
How can I return the string in a.txt back to the pipeline?
Thanks
You could try use a script to get the content of the txt file and set a variable $var for the content. Then use Logging commands to set another variable in the variable service of taskcontext. This variable is exposed to the following tasks as an environment variable.
echo "##vso[task.setvariable variable=testvar;]$var"

Bash script seems to be ignoring first variable

I am trying to make a simple script to swap between my server and main computer to compile nginx, but everytime I run the script, it ignores the first variable in $nginxsrc which is $code.
I stripped the build stuff out, because its not relevant to the question.
#!/bin/bash
home="/home/michael"
code="/src/nginx"
NGINX="nginx-1.13.11"
nginxsrc="$code/$NGINX"
echo "$code"
echo "$NGINX"
echo "$nginxsrc"
Here is what happens when it runs:
$ sudo bash /usr/local/bin/build-nginx
/src/nginx
nginx-1.13.11
/nginx-1.13.11
I have tried putting them in {} like so: nginxsrc="${code}/${NGINX}"
I have tried with and without quotes: nginxsrc=$code/$NGINX
My server is running ubuntu 16.04.4 LTS 64-bit with all the latest updates.
Bash version is 4.3.48
Obviously the expected result is:
/src/nginx
nginx-1.13.11
/src/nginx/nginx-1.13.11
This will happen when you have carriage returns in your file -- your file was saved with DOS-style line endings:
Display such a file:
$ cat -e cr.sh
code="/src/nginx"^M$
NGINX="nginx-1.13.11"^M$
nginxsrc="$code/$NGINX"^M$
echo "$code"^M$
echo "$NGINX"^M$
echo "$nginxsrc"^M$
and run it with tracing on
$ bash -x cr.sh
+ code=$'/src/nginx\r'
+ NGINX=$'nginx-1.13.11\r'
+ nginxsrc=$'/src/nginx\r/nginx-1.13.11\r\r'
+ echo $'/src/nginx\r\r'
/src/nginx
+ echo $'nginx-1.13.11\r\r'
nginx-1.13.11
+ echo $'/src/nginx\r/nginx-1.13.11\r\r\r'
/nginx-1.13.11
Edit your files in an editor where you can set "unix" line endings, or fix it with dos2unix or
sed -i 's/\r$//'
Not sure how helpful it will be, but on my Ubuntu this actually works as expected:
jhartman#wieloryb:~$ bash /tmp/xxx
/src/nginx
nginx-1.13.11
/src/nginx/nginx-1.13.11
This sounds so unbelievable that there is any kind of bug in Bash around variables.
As you wrote, the snippet you've posted is just an extract. Perhaps somewhere in fragment not posted here there is an operation on your $code variable.
All I can suggest is to run it in debug using bash -x <script>, e.g.:
jhartman#wieloryb:~$ bash -x /tmp/xxx
+ home=/home/michael
+ code=/src/nginx
+ NGINX=nginx-1.13.11
+ nginxsrc=/src/nginx/nginx-1.13.11
+ echo /src/nginx
/src/nginx
+ echo nginx-1.13.11
nginx-1.13.11
+ echo /src/nginx/nginx-1.13.11
/src/nginx/nginx-1.13.11
This should help you to narrow down what is happening.
Good luck & best regards,
Jarek

Executing local script/command on remote server

I have a command that I want to run on machine B from machine A. If I run the command on machine B locally, it works fine.
Here is the command:
for n in `find /data1/ -name 'ini*.ext'` ; do echo cp $n "`dirname $n `/` basename $n
.ext`"; done
From machine A, I issue this command
ssh user#machineB for n in `find /data1/ -name 'ini*jsem'` ; do echo cp $n "`dirname $n `/` basename $n .jsem`"; done
But I get error syntax error near unexpected token do
What is wrong? I think it has something to do with double quotes, single quotes, semi colon because executing command ssh user#machineB ls works fine. So not issue of authentication or something else.
Thanks
Put your code in a script, myScript.sh and execute it, just like ls: ssh user#machineB myScript.sh

save wild-card in variable in shell script and evaluate/expand them at runtime

I am having trouble running the script below (in Cygwin on win 7 mind you).
Lets call it "myscript.sh"
When I run it, the following is what I input:
yearmonth: 2011-03
daypattern: 2{5,6,7}
logfilename: error*
query: WARN
#! /bin/bash
yearmonth=''
daypattern=''
logfilename=''
sPath=''
q=''
echo -n "yearmonth: "
read yearmonth
echo -n "daypattern: "
read daypattern
echo -n "logfilename: "
read logfilename
echo -n "query: "
read q
cat "$yearmonth/$daypattern/$logfilename" | grep --color $q
The output I get is:
cat: /2011-03/2{5,6,7}/error* No such
directory of file exists.
However, if I enter daypattern=25 OR daypattern=26 etc. the script will work.
Also, of course if I type the command in the shell itself, the wildcards are expanded as expected.
But this is not what I want.
I want to be able to PROMPT the user to enter the expressions as they need, and then later, in the script, execute these commands.
Any ideas how this can be possible?
Your help is much appreciated.
Try eval, this should work for the {a,d} and * cases
eval grep --color $q ${yearmonth}/${daypattern}/${logfilename}
Use quote to prevent wildcard expansion:
$ a="*.py"
$ echo $a
google.py pair.py recipe-523047-1.py
$ echo "$a"
*.py

Resources