I'm having an environment variable that get's printed to a file which is then read by my program. When the variable gets written to the file it looks like this:
-----BEGIN
,RSA
,PRIVATE
,KEY-----
,MIIEowIBAAKCAQEAtxPgpPqD1cZdoTeOMvOnqp0NkkCqcMsn8V4j9KrFWpPxiweu
,H1r69S2ssmuqtleLVKk2kwgTn6x+AvcqgTBLsjnfpPmD2mBKvTqCvaBT2VXdxGiA
,dlp etc....
When it should look like this:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtxPgpPqD1cZdoTeOMvOnqp0NkkCqcMsn8V4j9KrFWpPxiweu
H1r69S2ssmuqtleLVKk2kwgTn6x+AvcqgTBLsjnfpPmD2mBKvTqCvaBT2VXdxGiA
dlpJMJAvCwBsDnDRilSRoNja4DpF26bHSQePwZF1/4OqnF6GtvGcPPPENiJkjxr/ etc...
My script command looks like this:
- printf '%s\n', $PRIVATE_KEY > $CI_PROJECT_DIR/private.pem
What am I doing wrong?
printf '%s\n' "$PRIVATE_KEY" > "$CI_PROJECT_DIR"/private.pem
Quote "$PRIVATE_KEY" to prevent it from being split into separate words. As a rule of thumb, always quote variable expansions to prevent accidental mangling of their values. It's a good habit to get into.
Also, remove the trailing comma from '%s\n',. Shell script arguments are not comma-separated.
Related
I have these file names that literally have double quotes in the path to deal with special characters issues, I want to loop through and echo the file paths while preserving the quotes, this seems to remove them:
for value in temp/sample."sample.id1".genotypes.txt temp/sample."sample.id2".genotypes.txt; do echo $value; done
I tried this but no luck:
for value in temp/sample."sample.id1".genotypes.txt temp/sample."sample.id2".genotypes.txt; do echo '${value}'; done
How do I do this?
You need to quote the strings to preserve the double quotes:
for value in 'temp/sample."sample.id1".genotypes.txt' 'temp/sample."sample.id2".genotypes.txt'; do
echo "$value"
done
Otherwise, writing some."thing" is identical to some.thing because the shell interprets the quotes.
You can also escape it :
for value in temp/sample.\"sample.id1\".genotypes.txt temp/sample.\"sample.id2\".genotypes.txt; do echo $value; done
for things like this, I like to use a slightly different approach that looks like a better design to me:
# make an array with the data
mapfile -t ary <<"EOF"
temp/sample."sample.id1".genotypes.txt
temp/sample."sample.id2".genotypes.txt
EOF
# use the data from the array
for f in "${ary[#]}"; do
printf '%s\n' "$f"
done
It will make your life a bit easier if your data grows, and you can then very easily transfer it to another file. Of course, if it's only for a one-time use (e.g., you made an error when naming your files and you only want to rename them), then learn how to have Bash properly parse the quotes as shown in the other answers (escaping them or using single quotes).
I would like to do a printf of variables, strings and new lines to a file in bash, and in one line. I would of used echo, but echo seems to be interpreted differently and on other questions have recommended printf.
NAME="karl"
printf %"s\n" this is $(NAME) hello! > my_file
When I do a cat my_file I'd like it to look as the following:
this
is
karl
hello!
I think you just want this:
name="karl"
printf "%s\n" this is "$name" hello! > my_file
The only issue with your code was that you were using $() (a command substitution) rather than a standard parameter expansion. That said, your format specifier looked strange, as it is normally written %s (it still works written your way, because the shell consumes the quotes).
Quotes are always a good idea to prevent word splitting (e.g. spaces in the name would go on separate lines) and glob expansion (a name like a* would expand to a list of paths starting with a).
try replacing the printf line with
sed 's/[[:space:]]/\n/g ' <<< "this is ${NAME} hello!" > my_file
I am writing a Bash script that creates a CMakeLists.txt file for a project.
The problem arises at this portion:
echo "file(GLOB projSRC src/*.cpp)" >> CMakeLists.txt
After that, I need the program to output ${SOURCES} into CMakeLists.txt
I don't mean a variable in the script named SOURCES, I mean it should actually write the plaintext ${SOURCES}.
What I mean is, the final file should look this like:
arbitrary_command(target PROJECT sources ${SOURCES})
and not like:
arbitrary_command(target PROJECT sources [insert however bash messes it up here])
How can I do this in my Bash script?
Use single quotes, not double quotes, for a literal string:
echo 'file(GLOB ${projSRC} src/*.cpp)' >> CMakeLists.txt
That said, you might consider using a heredoc (or even a quoted heredoc) in this case, to write the entire file as one command:
cat >CMakeLists.txt <<'EOF'
everything here will be emitted to the file exactly as written
${projSRC}, etc
even over multiple lines
EOF
...or, if you want some substitutions, an unquoted heredoc (that is, one where the sigil -- EOF in these examples -- isn't quoted at the start):
foo="this"
cat >CMakeLists.txt <<EOF
here, parameter expansions will be honored, like ${foo}
but can still be quoted: \${foo}
EOF
You can also have multiple commands writing output to a single redirection, to avoid paying the cost of opening your output file more than once:
foo=this
{
echo "Here's a line, which is expanded due to double quotes: ${foo}"
echo 'Here is another line, with no expansion due to single quotes: ${foo}'
} >CMakeLists.txt
May be I don't understand your question...
But
echo \${SOURCES}
will print
${SOURCES}
for you.
This is pretty basic, I guess I'm missing something really obvious...
The following sequence should explain it:
$ cat read_file_names.sh
#!/bin/bash
for i in $# ; do
echo "$i"
done
$ touch "filename has many spaces"
$ ./read_file_names.sh filename\ has\ many\ spaces
filename
has
many
spaces
ideally, the command line will have quotes around the filename as in:
$ ./read_file_names.sh "filename\ has\ many\ spaces"
The problem is that when allowing bash to auto-complete the filename (by hitting tab), the file name is left unquoted. Instead, it has a backslash-space "\ " to signal a space. I understand I can add quotes manually, but that would be tedious and a poor user experience.
I'm looking for a solution which assigns the entire file name to the for-loop variable, so that the output looks something like this:
$ ./read_file_names.sh filename\ has\ many\ spaces
filename has many spaces
The backslashes are working. It's your debugging printer that's wrong:
for i in $# ; do
That needs to be:
for i in "$#"; do
Otherwise, the argument string is inserted unquoted into the for expression and then word-split.
I wrote a bash script which automatically configures a setting file for some application.
The application uses a similar syntax to /etc/sysconfig/network file, the only exception is that it requires the values to be in double quotes " ".
So the line in the script looks something like this, but I don't know how to allow the double quotes of the ip address within the echo:
echo " ipaddr="1.1.1.1" " > file
How can it be done?
Escape the quotes with a backslash character or use single quotes:
echo "ipaddr=\"1.1.1.1\""
echo 'ipaddr="1.1.1.1"'
The other answers all provide excellent ways of solving your problem. I'd just like to add one using printf, that can make things comfortable if, e.g., the ip address is stored in a variable:
ip=1.1.1.1
printf 'ipaddr="%s"\n' "$ip" > file
But here again, as in the other answers, you'll need to play with both, single and double quotes.
Things will be comfortable in this case (still assuming the ip is in the variable ip), because with echo instead of printf, you'd have to use either:
echo "ipaddr=\"$ip\"" > file
# or
echo 'ip addr="'"$ip"'"' > file
(ok, it's not a big deal, but I usually like printf better than echo in bash).
You have at least two options:
Escape the double-quotes with single-quotes:
echo ' ipaddr="1.1.1.1" ' > file
Escape the double-quotes with backslashes:
echo "ipaddr=\"1.1.1.1\"" > file
In general, you can use a backslash to escape any single character; and you can use one type of quote to escape the other.
you got the choice:
you can use different quotes inner and outer of the echo
echo "ipaddr='1.1.1.1'" > file
echo 'ipaddr="1.1.1.1"' > file
you can escape the quotes:
echo "ipaddr=\"1.1.1.1\"" > file
or you can make it simpler (but with escapes on the quotes):
echo ipaddr=\"1.1.1.1\" > file