KSH Resolving Environmental Variables for an Entire File - environment-variables

I have a list of file names with environment variables in them. I'd like to read the file line by line and then set a variable to the read in line however have the envirnment variable translated to the appropriate environment variable. Here is my script so far:
#!/bin/ksh
. /test/currentEnv.sh
while read line
do
echo $line
done < $1
if my source file is:
foo1$ENVVAR1.csv
foo2$ENVVAR2.csv
foo3$ENVVAR3.csv
and my Environment variables in currentEnv.sh are
$ENVVAR1=hello; export ENVVAR1
$ENVVAR2=world; export ENVVAR2
$ENVVAR3=test; export ENVVAR3
I'd like the results of the script to be
foo1hello.csv
foo2world.csv
foo3test.csv
currently it just dumps out the original file:
foo1$ENVVAR1.csv
foo2$ENVVAR2.csv
foo3$ENVVAR3.csv
Edit
I was able to get the majority of my files resolved using:
#!/bin/ksh
. /test/currentEnv.sh
while read line
do
eval echo $line
done < $1
however some of my variables are in the middle of string like:
foo3$ENVVAR3_bar.csv
this seems to look for an env variable $ENVVAR3_bar and doesn't find it I need this to output:
foo3test_bar.csv

You declare a variable without the dollar sign:
$var=value # no
var=value # yes
Since underscore is a valid character for a variable name, ksh is trying to expand the variable named ENVVAR3_bar: you need to use braces to separate the variable name from the surrounding text:
foo3$ENVVAR3_bar.csv # no
foo3${ENVVAR3}_bar.csv # yes

Related

Zsh - export: not valid in this context: charge"}'

I have .env file with value as
export AB_EXPERIMENT_NAMES='{"consumer_estimated_delivery_charges_v1":"Delivery charge"}'
but when I run it like below I am getting the error
export: not valid in this context: charge\"}\"'
export $(cat .env | xargs -0)
The issue seems to be in the space in Delivery charge.
How can I resolve this.
First of all, instead of doing export $(cat .env | xargs -0), you should just do
source .env
But for the sake of it, let's say that you actually want to read the export statements from .env and then pass as arguments them to another command, but without the word export in front of them. The right way to do it in Zsh would be
<command> ${${(fz)"$( < .env )"}:#export}
This works as follows:
< .env reads the contents of .env and passes them to standard input. If there's no command connected to < (as is the case here), then Zsh will implicitly use cat.
$( < .env ) captures the output of < .env and expands it to a string. Note that using $( < ... ) is faster than using $( cat ... ), because Zsh does not actually spawn a separate process for it.
"$( < .env )" ensures line breaks are preserved.
${(f)...} splits the string on newlines.
${(z)...} splits the string into shell words.
In the resulting array of shell words, ${...:#export} removes all instances of the word export.
See http://zsh.sourceforge.net/Doc/Release/Expansion.html for more info.

How to setup completion of environment variable names in zsh?

In bash when I try to use autocompletion in double-quoted strings it works:
E.g.
echo "My home directory is $HO<t>"
# expands to
echo "My home directory is $HOME"
But when I try the same thing in zsh it just does nothing.
At the same time it works outside strings:
echo My\ home\ directory\ is\ $HO<t>
# expands to
echo My\ home\ directory\ is\ $HOME
Is it possible to make it work the same as bash?
Zsh completion has a bug where completion of parameter names fails if a partial parameter name is followed by a ".
As a workaround, just remove the final " from your string before pressing Tab. Then, Zsh's completion will work correctly and it will automatically add the final " for you.

How to escape a $-sign in a dockerfile?

I am trying to write a dockerfile in which I add a few java-options to a script called envvars.
To achieve that I want to append a few text-lines to said file like so:
RUN echo "JAVA_OPTS=$JAVA_OPTS -Djavax.net.ssl.trustStore=${CERT_DIR}/${HOSTNAME}_truststore.jks" >> ${BIN_DIR}/envvars
RUN echo "JAVA_OPTS=$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${PWD_TRUSTSTORE}" >> ${BIN_DIR}/envvars
RUN echo "export JAVA_OPTS" >> ${BIN_DIR}/envvars
The issue here is, that I want the misc. placeholders ${varname} (those with curly braces) to be replaced during execution of the docker build command while the substring '$JAVA_OPTS' (i.e. those without braces) should be echoed and thus added to the envvars file verbatim, i.e. in the end the result in the /usr/local/apache2/bin/envvars file should read:
...
JAVA_OPTS=$JAVA_OPTS -Djavax.net.ssl.trustStore=/usr/local/apache2/cert/myserver_truststore.jks
JAVA_OPTS=$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=my_secret
export JAVA_OPTS
How can one escape a $-sign from variable substitution in dockerfiles?
I found hints to use \$ or $$ but neither worked for me.
In case that matters (which I hope/expect not to): I am building the image using "Docker Desktop" on Windows 10 but I would expect the dockerfile to be agnostic of that.
first you need to add this # escape=` to your Dockerfile since \ is an escape charachter in the Dockerfile . then you can use \$ to escape the dollar sign in the RUN section
Example:
# escape=`
RUN echo "JAVA_OPTS=\$JAVA_OPTS -Djavax.net.ssl.trustStore=${CERT_DIR}/${HOSTNAME}_truststore.jks" >> ${BIN_DIR}/envvars
that will be JAVA_OPTS=$JAVA_OPTS in your env file

variable does not exist in sas data set

I am trying to check whether variable GROUP exist in SAS data set file or not from the UNIX command but unfortunately it's showing that GROUP variable does not exist in the data set,However GROUP variable is present in SAS data set.
In my command for case sensitive and whole word match I am using i and w options of grep command respectively. But still UNIX command is not giving the expected result.I s there any way to fix this issue?
Below is the command which I am using:
sasfile="sasdata"
rwords="GROUP"
cat $sasfile | grep -iqw "$rwords"
Thank you
As mentioned in earlier comment
SAS data sets are stored in disk files using a proprietary format.
There may be encodings and storage methodologies that do not yield the
information you seek in a plain text examination of said disk file.
Running SAS code in a SAS session is the definitive way to glean information about a data set.
What will that code look like ?
Proc CONTENTS
Data step or macro code that uses VARNAME function
... many other ways ...
In UNIX SAS can use stdio.
From "SAS(R) 9.2 Companion for UNIX Environments", STDIO System Option: UNIX
Details
This option tells SAS to take its input from standard input (stdin),
to write its log to standard error (stderr), and to write its output
to standard output (stdout).
This option is designed for running SAS
in batch mode or from a shell script. If you specify this option
interactively, SAS starts a line mode session.
The STDIO option
overrides the DMS, DMSEXP, and EXPLORER system options. The STDIO
option does not affect the assignment of the Stdio, Stdin, and Stderr
filerefs. See Filerefs Assigned by SAS in UNIX Environments for more
information.
For example, in the following SAS command, the file
myinput is used as the source program, and files myoutput and mylog
are used for the procedure output and log respectively.
sas -stdio < myinput > myoutput 2> mylog
If you are using the C shell, you should
use parentheses:
(sas -stdio < myinput > myoutput ) >& output_log
With -stdio you want a short SAS program that can indicate if a variable is present in a data set, or perhaps emit a list of variables in a data set for further shell processing. A Proc CONTENTS step is short and sweet.
So looking for your proverbial needle in a haystack
sasfile=<path to data set file>/<dataset>.sas7bdat
needle=GROUP
echo "Proc CONTENTS data=""$sasfile""" | sas -stdio | grep $needle
The default CONTENTS output might contain yield some false matches. So you could also try
echo "Proc CONTENTS noprint data=""$sasfile"" out=list;data _null_;set list;file print;put name;"
| sas -stdio
| grep -i "GROUP"
You could try:
sasfile="sasdata"
rwords="GROUP"
grep -iw "$rwords" "$sasfile"
The only difference between these and your original commands is that I omitted cat and grep's quiet flag -q.
Sample input in sasdata:
fasd group
fdsfds fdsfdsa
fdsfd as GROUP afdsfdsa
Output:
fasd group
fdsfd as GROUP afdsfdsa
The -q flag of grep will suppress standard output but echo $? can retrieve the return value of grep. Using the same input file as before:
grep -iqw "$rwords" "$sasfile" # No stout
echo $? # Prints 0, means grep succeeded
grep -iqw "word" "$sasfile" # No stout
echo $? # Prints 1, means grep failed

Jenkins EnvInject plugin - Environment variable value containing multiple lines

I followed the suggestions from this post on how to use the EnvInject plugin to create and set Jenkins environment variables. I'm using the "Inject environment variables" in post build step and set "Properties File Path"
The windows batch script create a environment variable OPS and writes it to a property file : results.txt which contains multiple lines , like :
OPS= This is line one,
This is two
This is three
Challenge: OPS picks up only the first line from results.txt and skips the rest of the lines.
How do I set OPS have all the lines as its value ?
cd C:\To\Test\Class\Path
java utilities.LogExtractor>ops.txt
#echo off
setlocal EnableDelayedExpansion
set LF=^
rem *** Two empty lines are required for the linefeed
FOR /F "delims=" %%a in (ops.txt) do (
set var=!var!!LF!%%a
)
set var=!var!!LF!
echo OPS=!var! > %JENKINS_HOME%\jobs\%JOB_NAME%\builds\%BUILD_NUMBER%\results.txt
and I set the "Properties File Path" to %JENKINS_HOME%\jobs\%JOB_NAME%\builds\%BUILD_NUMBER%\results.txt
From the source code, I'd say it uses java.util.Properties to load the file, calling the load method. The documentation says you can escape a line break with a backslash, so using
OPS= This is line one,\
This is two\
This is three
should be sufficient. (Be careful, whitespace at the beginning of the line is ommitted.)

Resources