Bash works as expected
$ echo '{"foo": "0"}' | jq 'select(.foo == "0")'
{
"foo": "0"
}
But in Powershell,
PS> echo '{"foo": "0"}' | jq 'select(.foo == "0")'
PS>
Why powershell results this?
You have to backslash the doublequotes unfortunately.
'{"foo": "0"}
{"foo": "1"}' | jq -c 'select(.foo == \"0\")'
{"foo":"0"}
Related
I am trying to convert a shell script to PowerShell script, I am facing issue with below shell commands
label=`echo -n "signing key" | hexdump -ve '/1 "%02x"'`
sign_nist="00000001${label}0000000100"
/testing$ echo $sign_nist
000000017369676e696e67206b65790000000100
/testing$ echo -n $sign_nist | sed -e 's/../\\x&/g'
\x00\x00\x00\x01\x73\x69\x67\x6e\x69\x6e\x67\x20\x6b\x65\x79\x00\x00\x00\x01\x00
/testing$ echo -ne "$(echo -n $sign_nist | sed -e 's/../\\x&/g')"
signing key
when I try to do the same thing in PowerShell using the below commands my output is different
PS C:\testing> $sign_nist
000000017369676E696E67206B65790000000100
PS C:\testing>
$prep = $sign_nist -split '(..)' -ne ''
for($i = 0; $i -lt $prep.length; $i++)
{
$prep[$i] = [System.Convert]::ToUInt32($prep[$i],16)
}
$sign_key_input=$prep -join '';
$sign_key_input
00011151051031101051101033210710112100010
could someone please help me how to get signing key to $sign_key_input with PowerShell?
Thanks in advance for the help.
I think appending \x for each byte works for linux to treat it as hex value but how to indicate the same in powershell?
I'm trying to use jq's --arg syntax to pass a variable from the shell to a jq filter.
If I run the following command, the jq query works as expected:
TS_SEC_START=1534574204 \
kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \
jq --arg TS_SEC_START 1534574204 --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
-s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == "mysvc.prod"))'
-->
Found 3 pods, using pod/flagger-6dc6fd7d85-z294g
[
{
"level": "error",
"ts": "2021-08-16T02:41:34.128Z",
"caller": "controller/scheduler.go:163",
"msg": "Canary mysvc.prod not found",
"canary": "mysvc.prod",
"stacktrace": "github.com/fluxcd/flagger/pkg/controller.(*Controller).advanceCanary\n\t/workspace/pkg/controller/scheduler.go:163\ngithub.com/fluxcd/flagger/pkg/controller.CanaryJob.Start.func1\n\t/workspace/pkg/controller/job.go:39"
}
]
However, when I try to pass mysvc.prod as an arg, I receive 0 responses.
TS_SEC_START=1534574204 SERVICE_NAME=mysvc RELEASE_NAMESPACE=prod \
kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \
jq --arg TS_SEC_START 1534574204 --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
-s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == $SVC))'
I've tried a few different options here, e.g. .canary == "$SVC" and `.canary == "$SERVICE_NAME.$RELEASE_NAMESPACE" but I can't get it to work.
What am I doing wrong?
-->
Found 3 pods, using pod/flagger-6dc6fd7d85-z294g
[]
In general, you can't do this:
MYVAR=12345 printf "%s\n" "$MYVAR"
When you prefix a shell command with MYVAR=12345 you are modifying the environment that is passed to that process, in this case printf. However, the $MYVAR expression is expanded in the shell and no MYVAR variable ever exists in the shell.
Furthermore, when you set variables like this, they are only passed to that command, not the entire pipeline.
So in this example:
TS_SEC_START=1534574204 \
SERVICE_NAME=mysvc \
RELEASE_NAMESPACE=prod \
kubectl -n istio-system logs deployment/flagger --tail=50 | \
grep '^{' | \
jq \
--arg TS_SEC_START 1534574204 \
--arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
-s \
'
map(
select(
.ts |
(split(".")[0] + "Z") |
fromdateiso8601 > ($TS_SEC_START | tonumber)
) |
select(.canary == $SVC)
)
'
The three environment variables are visible to kubectl and nothing else. They are not visible to grep or jq (although neither of them are looking for such environment variables in the first place) and they are not visible to the shell itself as it expands those commands.
I registered the script to crontab to run every 10 minutes. When I run the script, the log is printed, but if I put it on the cron tab and wait, the log does not appear, so it seems that it does not work. If you have anything I need to add or edit, please let me know :(
my sh script
#!/bin/sh
pslist=`ps -ef | grep ffprobe | awk '{print $2}'`
pscount=`ps -ef | grep ffprobe | wc -l`
logs='/apps/kMobile/kEncoderPy/batch/kill_ffprobe.log'
timestamp=`date +%Y%m%d--%H:%M`
echo "[$timestamp] Kill the Batch process Start :: "$timestamp >> $logs
echo "[$timestamp] process ffprobe running count :: "$pscount >> $logs
for pid in $pslist
do
rtime=`ps -p $pid -o etime | tail -1`
rtime=$rtime | tr -d ' '
minutes=${rtime:6:2}
if [$rtime != "ELAPSED" ]; then
if [ $minutes -gt 10 ]; then
`kill -9 $pid`
echo "[$timestamp] passed 10 minute kill process id : "$pid >> $logs
echo "[$timestamp] process kill after ffprobe running count : "$psount >> $logs
fi
fi
done
my crontab -e
*/10 * * * * /apps/kMobile/batch/kill_ffprobe.sh
Using Cygwin sed, on windows command prompt, sed takes \\\ to convert a path to : e.g.
C:\>echo 'PATH_TO_SOURCES' | sed 's/PATH_TO_SOURCES/\C:\\\WorkArea\\\workspace\\\sources/g'
would result in C:\WorkArea\workspace\sources
But when I have to use the same in Jenkins pipeline, it takes \\\\\\ in the path to convert it to single . Here is the command line I had to generate to give me 'C:\WorkArea\workspace\sources'
stage('SED')
{
steps {
script {
cfgFile="MyCfg.xml"
dir(AutomationScripts) {
bat (""" cat MyCfg.xml | sed "s/PATH_TO_SOURCES/\C:\\\\\\WorkArea\\\\\\workspace\\\\\\sources/g" > newMyCfg.xml""")
}
}
}
}
Update: I experimented by changing quotes as mentioned in the comments, but nothing seemed to be changed. Here are the pipelines (starting with bat) and the results:
Pipeline: bat (" echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed 's/PATH_TO_SOURCES/\\C:\\\\\\WorkArea\\\\\\workspace\\\\\\sources/g' ")
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed 's/PATH_TO_SOURCES/\C:\\\WorkArea\\\workspace\\\sources/g'
'C:\WorkArea\workspace\sources'
Pipeline: bat (" echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed 's/PATH_TO_SOURCES/\\C:\\WorkArea\\workspace\\sources/g'")
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed 's/PATH_TO_SOURCES/\C:\WorkArea\workspace\sources/g'
'C:WorkAreaworkspacesources'
Pipeline: bat ("""echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed "s/PATH_TO_SOURCES/\\C:\\WorkArea\\workspace\\sources/g" """)
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed "s/PATH_TO_SOURCES/\C:\WorkArea\workspace\sources/g"
'C:WorkAreaworkspacesources'
Pipeline: bat ("echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed 's/PATH_TO_SOURCES/\\C:\\\\WorkArea\\\\workspace\\\\sources/g'")
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed 's/PATH_TO_SOURCES/\C:\\WorkArea\\workspace\\sources/g'
'C:WorkAreaworkspacesources'
Pipeline: bat ("""echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed "s/PATH_TO_SOURCES/\\C:\\\\WorkArea\\\\workspace\\\\sources/g" """)
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed "s/PATH_TO_SOURCES/\C:\\WorkArea\\workspace\\sources/g"
'C:WorkAreaworkspacesources'
Although, it was a bat call and supposed to behave the same as it happens at the command prompt.
Looks like Pipeline itself escaping \.
Any idea if I'm missing something here?
I realized that that groovy pipeline script escapes \, so to get C:\Program Files\Microsoft, so have to use \\ i.e. C:\\Program Files\\Microsoft.
On the other hand, (Observed in Windows cygwin 64) sed takes \\\ to get \ as mentioned in my original post i.e.
C:\>echo 'PATH_TO_SOURCES' | sed 's/PATH_TO_SOURCES/\C:\\\WorkArea\\\workspace\\\sources/g' would result in C:\WorkArea\workspace\sources
So using sed in the groovy pipeline, at first groovy would do the escaping in the path string and then the result would be passed on to the sed, which would again do its own escaping on the string, so we have to add \\\\\\ in our paths, which would be escaped by the groovy and it would become \\\. Then sed would escape \\\ to a \. Here is the example I posted, is working like that:
Pipeline: bat (" echo 'PATH_TO_SOURCES' | c:\\cygwin64\\bin\\sed 's/PATH_TO_SOURCES/\\C:\\\\\\WorkArea\\\\\\workspace\\\\\\sources/g' ")
Output: C:\>echo 'PATH_TO_SOURCES' | c:\cygwin64\bin\sed 's/PATH_TO_SOURCES/\C:\\\WorkArea\\\workspace\\\sources/g'
'C:\WorkArea\workspace\sources'
I have a few filenames in a directory
blabla.01
blabla.02
...
I'm trying to make a new file with the following format:
01 new stuff here
02 more new stuff
...
I wrote a script and dumbed it down a bit:
#!/bin/bash
FILES=$(find . -type f -name "blabla*" | awk -F'[.]' '$(NF-1)>=1' | sort)
for f in $FILES
do
echo -n $f | cut -d "." -f 3
echo "test"
done
the 'test' will be the output of another code..
However in this example i get something like:
01
test02
test
Thanks
Try
printf '%s%s\n' "$(echo "$f" | cut -d . -f3)" "test"
The echo | cut could probably be replaced with something like "${f##*.}" if you always want the laat field.