Hash ("#") symbol in /etc/environment causes string to be split - linux

I'm trying to add an environment variable to my system via
sudo nano /etc/environment
The value is a long string containing a hash, #.
With the # included, the string is not stored fully; characters after the # are gone.
Without the # included, the string is stored fully.
I have tried to wrap the string in " ":
MY_VARIABLE="34534554345 # DFGDGDFG"
I expect the variable to be stored fully, like this:
34534554345#DFGDGDFG
Not this:
34534554345

PAM interprets /etc/environment, not a shell. It's intended to be simple KEY=VALUE on each line with no need for quotes. # marks a comment and there is no way to escape it.
You can use /etc/profile to define your environment variable. It should make it available system wide in most cases.
/etc/environment
TEST2="12345#6789"
/etc/profile
export TEST="12345 #6789"
Result:
root#tempmon:~ $ env|grep TEST
TEST=12345# 6789
TEST2=12345

Related

Bash prompt variables does not work inside a bash function

I'm working on a prompt customization, but for some reason, when I use the \u, \h and \W variables as is it works perfectly, but when I put them inside a function, they are displayed as "\u" or "\W" instead of their values.
...
print_user()
{
echo -e "\001\u\002#\001\h\002"
}
print_dir()
{
echo -e "\001${YELLOW}\002\001\W\002\001${RESET_ATTR}\002"
}
PS1='[$(print_user) on $(print_dir)] $(get_git_repo) \001\n\002$(print_prompt) '
This displays as:
[\u#\h on \W]
>
If I move them outside of the function like so
PS1='[\[\u\]#\[\h\] \[${YELLOW}\]\[\w\]\[${RESET_ATTR}\]] $(get_git_repo) \[\n\]$(print_prompt)'
It works fine, and displays the current directory with the username and hostname:
[myusername#arch on ~]
>
Is this just how bash works? Is there a different way of doing it so it will work? Why is it that inside of a function it won't display the variables' values but outside of a function it does?
From the man page, under PROMPTING
Bash allows these prompt strings to be customized by inserting a number of
backslash-escaped special characters that are decoded as follows:
[...]
After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the
promptvars shell option (see the description of the shopt command under SHELL BUILTIN COMMANDS below).
By the time the shell expands $(print_user) to add \u to the string, it is too late to decode it, so the literal string \u remains in the prompt.
One alternative is to use PROMPT_COMMAND to execute a function that defines PS1 dynamically, just before it is displayed, instead of embedding command substitution in the value of PS1 itself.
make_prompt () {
PS1="[$(print_user) on $(print_dir)] $(get_git_repo)"
PS1+='\[\n\]'
PS1+="$(print_prompt) "
}
PROMPT_COMMAND=make_prompt
Now, print_user will have been called before the shell decodes the value of PS1, by which time all the prompt escapes will be present.

how to use user defined variables in file path concatenation using shell script

$var='system1'
data=C:/data/$var/current_extract/*
Output should be
data=C:/data/system1/current_extract/*"
but i still see the result C:/data/$var/current_extract/* $var value is
**system1** not showing the path
Remove the dollar in the assignment
var='system1'
For setting a variable in Linux variable_name=value. For displaying it you have to prefix the variable name with $ symbol. for example echo $variable_name
var='system1'
data=C:/data/$var/current_extract/*

Can I prevent echo from expanding env vars?

I have an automatic setup script that is executed when a new user is created. It runs this line of code to set up the golang environment: echo "export PATH="$PATH:$GOPATH/bin"" >> ~/.profile
But this will expand all environment variables before writing into the file. Is there a way to write export PATH="$PATH:$GOPATH/bin" into a file from the command line without expanding the environment variables?
Try:
echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.profile
Single-quoted strings in POSIX-like shells (such as bash) treat their content as literals, which is what you want here.
The only reason to use a double-quoted string here would be to selectively expand variable references up front - which doesn't apply in your case.
That said, here's an example:
$ echo "Honey, I'm \"$USER\" and I'm \$HOME."
Honey, I'm "jdoe" and I'm $HOME.
Backslash-escaping is used to escape embedded " and $ instances that should be treated as literals.
As for what you tried:
"export PATH="$PATH:$GOPATH/bin""
is actually a string concatentation, composed of 3 separate strings:
"export PATH=", which, as a double-quoted string that happens not to contains $-prefixed interpolation elements, expands to literal export PATH=
$PATH:$GOPATH/bin, which, as an unquoted string, is subject to additional shell expansions, which not only involves expanding variables $PATH and $GOPATH to their respective values, but also applies word-splitting and pathname expansion (globbing).
"", which amounts to the empty string and is effectively ignored.
Note how POSIX-like shells allow you to compose larger strings (concatenate strings) by placing strings - unquoted or single-quoted or double-quoted - directly next to one another.

Setting environment variable with leading digit in bash

I need to set an environment variable called "64bit" (i.e. with a leading digit) in bash. However, bash variable names disallow a variable with a leading digit. I know a way to set it when invoking bash:
env 64bit=1 /usr/bin/bash
However, I'm looking for a way to change it in the currently running shell i.e. not by starting a new shell. I also know that csh allows variables to start with a digit, but I need to use bash.
Is there any way to achieve this?
You can also bypass the bash interpreter and define the variable directly with the bash internal functions:
$ gdb --batch-silent -ex "attach $$" \
-ex 'set bind_variable("64bit", "1", 0)' \
-ex 'set *(int*)(find_variable("64bit")+sizeof(char*)*5) = 1' \
-ex 'set array_needs_making = 1'
$ env | grep 64
64bit=1
As people point out, Bash does not allow variables starting with digits. It does however pass on unrecognized environment string to external programs, which is why the variable shows up in env but not in set.
As a workaround, you can work with a valid name like _64bit and then automatically inject your invalid variable name into commands you run:
#!/bin/bash
# Setup for injection hack
original=$PATH
PATH="/"
command_not_found_handle() {
PATH="$original" env "64bit=$_64bit" "$#"
}
# Your script and logic
_64bit="some dynamic value"
# This verifies that '64bit' is automatically set
env | grep ^64bit
Note that this particular method only works if you invoke through $PATH, not if you use relative or absolute path names.
If you do invoke by pathname, consider modifying PATH and invoking by name instead.

Read / Run Environment Variables in a text file

I have an app which runs and reads a text configuration file.
This points to several locations of configurations / outputs etc.
Is it possible to use environmental variables inside the text configuration file, rather than hardcoded paths?
LogFilePath=$LOG_FILE_PATH
vs
LogFilePath=/home/user/logs
When running, the application fails as it cannot expand the Environment Variable.
It will be sourced inside the shell before the application is run.
Thanks!
Recently I used this in a (bash) script:
#!/bin/bash
# ...
source config.file
# ...
Where config.file had lines like this:
export ORIG_PATH="${PATH:-.}:/bla/bla"
export SOMESETTING="${SOMEVAR:-"somedefault"},somedata"
...
So the ${parameter:-word} thing worked well for me: use default values, if parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted. (From man bash.)
HTH

Resources