Uppercase variable

Hello,
This is not a problem specific question.
While surfing on google to find a solution for the latest error messages I have received from command line, I found some suggestions regarding usage of linux commands:

Could it be a problem specific comment or in most cases, `` causes issue?
Normally I have been using this though and did not encounter any issue.

How come would linux detect uppercase variables as path?

Thank you
Boris

No.
The problem relates to nested `` , a pair of back-ticks inside another pair of back-ticks will cause errors.

It has nothing to do with PATH particularly. What if you made a variable called "BASH_REMATCH", what would happen? I picked this one because it does not come up very often here on the forums.
Answer: It is the name of an array. Your code could break regular expression searches in bash. None of the special variables bash uses are lowercase.
So, no matter what you do to lowercase variables, you will not mess up shell and other utilities do internally.

This is the output of the set command on my cygwin instance on Windows 7: It's BIG. Many,many variables. If
I use other than default software the variables may increase a lot - Oracle is an example.

$ set
ALLUSERSPROFILE='C:\ProgramData'
APPDATA='C:\Users\Owner\AppData\Roaming'
BASH=/bin/bash
BASHOPTS=cmdhist:complete_fullquote:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="4" [2]="12" [3]="3" [4]="release" [5]="x86_64-unknown-cygwin")
BASH_VERSION='4.4.12(3)-release'
COMMONPROGRAMFILES='C:\Program Files\Common Files'
COMPUTERNAME=OWNER-PC
COMSPEC='C:\Windows\system32\cmd.exe'
CYG_SYS_BASHRC=1
CommonProgramW6432='C:\Program Files\Common Files'
DIRSTACK=()
EUID=1000
EXECIGNORE='*.dll'
FP_NO_HOST_CHECK=NO
GROUPS=()
HISTFILE=/home/Owner/.bash_history
HISTFILESIZE=500
HISTSIZE=500
HOME=/home/Owner
HOMEDRIVE=C:
HOMEPATH='\Users\Owner'
HOSTNAME=Owner-PC
HOSTTYPE=x86_64
IFS=$' \t\n'
INFOPATH=/usr/local/info:/usr/share/info:/usr/info
LANG=en_US.UTF-8
LOCALAPPDATA='C:\Users\Owner\AppData\Local'
LOGONSERVER='\\OWNER-PC'
MACHTYPE=x86_64-unknown-cygwin
MAILCHECK=60
MINTTY_SHORTCUT='/cygdrive/c/Users/Public/Desktop/Cygwin64 Terminal.lnk'
NUMBER_OF_PROCESSORS=8
OLDPWD=/cygdrive/c/Users/Owner/Desktop
OPTERR=1
OPTIND=1
ORIGINAL_PATH='/cygdrive/c/ProgramData/Oracle/Java/javapath:/cygdrive/c/Program Files (x86)/Intel/iCLS Client:/cygdrive/c/Program Files/Intel/iCLS Client:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/Intel/OpenCL SDK/2.0/bin/x86:/cygdrive/c/Program Files (x86)/Intel/OpenCL SDK/2.0/bin/x64:/cygdrive/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files (x86)/Skype/Phone:/cygdrive/c/Users/Owner/.cargo/bin:/cygdrive/c/Users/Owner/AppData/Local/Programs/Python/Python35/Scripts:/cygdrive/c/Users/Owner/AppData/Local/Programs/Python/Python35:/cygdrive/c/Program Files (x86)/IDM Computer Solutions/UltraEdit'
OS=Windows_NT
OSTYPE=cygwin
PATH='/usr/local/bin:/usr/bin:/cygdrive/c/ProgramData/Oracle/Java/javapath:/cygdrive/c/Program Files (x86)/Intel/iCLS Client:/cygdrive/c/Program Files/Intel/iCLS Client:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/Intel/OpenCL SDK/2.0/bin/x86:/cygdrive/c/Program Files (x86)/Intel/OpenCL SDK/2.0/bin/x64:/cygdrive/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files (x86)/Skype/Phone:/cygdrive/c/Users/Owner/.cargo/bin:/cygdrive/c/Users/Owner/AppData/Local/Programs/Python/Python35/Scripts:/cygdrive/c/Users/Owner/AppData/Local/Programs/Python/Python35:/cygdrive/c/Program Files (x86)/IDM Computer Solutions/UltraEdit:/usr/lib/lapack'
PATHEXT='.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC'
PIPESTATUS=([0]="0")
PPID=35
PRINTER='HP Color LaserJet Pro MFP M477 PCL 6'
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER='Intel64 Family 6 Model 58 Stepping 9, GenuineIntel'
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3a09
PROFILEREAD=true
PROGRAMFILES='C:\Program Files'
PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$ '
PS2='> '
PS4='+ '
PSModulePath='C:\Windows\system32\WindowsPowerShell\v1.0\Modules\'
PUBLIC='C:\Users\Public'
PWD=/home/Owner
ProgramData='C:\ProgramData'
ProgramW6432='C:\Program Files'
SESSIONNAME=Console
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
SYSTEMDRIVE=C:
SYSTEMROOT='C:\Windows'
TEMP=/tmp
TERM=xterm
TMP=/tmp
TZ=America/Denver
UID=1000
USER=Owner
USERDOMAIN=Owner-PC
USERNAME=Owner
USERPROFILE='C:\Users\Owner'
WINDIR='C:\Windows'
_=env
windows_tracing_flags=3
windows_tracing_logfile='C:\BVTBin\Tests\installpackage\csilogfile.log'
gawklibpath_append ()
{
    [ -z "$AWKLIBPATH" ] && AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`;
    export AWKLIBPATH="$AWKLIBPATH:$*"
}
gawklibpath_default ()
{
    unset AWKLIBPATH;
    export AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`
}
gawklibpath_prepend ()
{
    [ -z "$AWKLIBPATH" ] && AWKLIBPATH=`gawk 'BEGIN {print ENVIRON["AWKLIBPATH"]}'`;
    export AWKLIBPATH="$*:$AWKLIBPATH"
}
gawkpath_append ()
{
    [ -z "$AWKPATH" ] && AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`;
    export AWKPATH="$AWKPATH:$*"
}
gawkpath_default ()
{
    unset AWKPATH;
    export AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`
}
gawkpath_prepend ()
{
    [ -z "$AWKPATH" ] && AWKPATH=`gawk 'BEGIN {print ENVIRON["AWKPATH"]}'`;
    export AWKPATH="$*:$AWKPATH"
}
profile_d ()
{
    _LC_ALL_SET_="${LC_ALL+set}";
    _LC_SAVE_="${LC_ALL-null}";
    LC_ALL=C;
    if [ "${_LC_SAVE_}" = "null" ]; then
        for file in /etc/profile.d/*.$1;
        do
            [ -e "${file}" ] && . "${file}";
        done;
        unset LC_ALL;
    else
        for file in /etc/profile.d/*.$1;
        do
            [ -e "${file}" ] && LC_ALL="${_LC_SAVE_}" . "${file}";
        done;
        LC_ALL="${_LC_SAVE_}";
    fi;
    unset file;
    unset _LC_ALL_SET_;
    unset _LC_SAVE_
}

Owner@Owner-PC ~
$
1 Like

Well Jim, it's nice to see that there are historical backticks in the output of set for things such as gawkpath_default :wink:

I must admit that I spent a few years writing awful code using backticks in my scripts and fighting with escapes and escaped escapes depending how many layers there were or if I was running things remotely. Compare these:-

ssh $trg grep  "'warning'  \`ls /app/logs/*\\\`date '+%Y'\\\`.TFC-log|sort -r\`"
ssh $trg grep  "'warning'  \$(ls /app/logs/*\$(date '+%Y').TFC-log|sort -r)"

Both are pretty awful and should probably have been replaced by something neater overall anyway, but the escaped back-ticks make it particularly horrible to decipher. Sadly I had to escape the $ to get that passed as literal test to the remote server so that it would then execute there. I'm not proud of it but it worked when we hardly knew what we were doing and so this sort of thing got used all over the place for a while, so deciphering it (and worse) became quite an effort. It is all tidied up/replaced now anyway. They are worse to understand if you are not the author because the scripts were rarely commented.

The really confusing part is trying to work out where a back-tick ends with all those escapes too. At least with the start of a call being $( and the end being ) you have a fighting chance and tools like vim can help you too because they recognise and highlight the 'other end' and a call.

I hope that this help (or my awful old-style code makes you squirm :o)
Robin

4 Likes

Hi all...

Bizarrely, I have switched from lowercase to uppercase for variables as they are easier to see straight away. The vast majority of tools/commands/utilities are lowercase and can _mingle_ with the variables visually whereas uppercase tend to stand out. I do pick names that are very literal and unlikely to coincide with those of the/any environment.

Examples: VERTICAL_GAIN and AUDIO_SAMPLE ...

On AudioScope I was _briefed_ about using back-ticks but they have long since gone, along with this, which is still valid on OSX 10.14.3's bash version, 3.2.57:
x=1; x=$[ ( x + 4 ) ]; echo "$x"<CR> ...

1 Like

Hi, Jim.

With the possible exception of csh , tcsh and friends, which use variable names like path and then they will make changes to the environment variable like PATH automatically (as I recall).

But in terms of Bourne shell and descendants, I agree, and good point ... cheers, drl

Regarding

ssh $trg grep  "'warning'  \$(ls /app/logs/*\$(date '+%Y').TFC-log|sort -r)"

You do not want to substitute any $-expression on the remote site by the calling site.
Then it is easier to use protective 'ticks' for the local site, so the remote side gets its contents unchanged. And have \' or " inside it that becomes ' or " on the remote side.

ssh $trg 'grep  "warning" $(ls /app/logs/*$(date "+%Y").TFC-log|sort -r)'

Or, assuming that ls -r does the same as sort -r ,

ssh $trg 'grep  "warning" $(ls -r /app/logs/*$(date "+%Y").TFC-log)'

Yes, I said that even the better version was awful code :o and I'm having to remember it because it's long since replaced/retired. I might even have a syntax error, but I just remember the horror of all those escapes :eek:

I'm off for a lie down.
Robin