Detecting unused variables...


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users Detecting unused variables...
# 8  
Old 06-11-2016
Well guys I have done some some experiments printf .
(All 'printf' statements now changed inside AudioScope.
Now consider the code below:-
Code:
#!/bin/sh --posix
clear
x=8
y=2
printf "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
y=4
printf "%b" "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
y=6
printf "%b" "\x1B[""$y"";""$x""fWorks but is POSIX and sh compliant...\n"
y=8
printf "%b" "\x1B[$y;$x""fWorks but is POSIX and sh compliant...\n"
y=10
printf "%b" "\x1B[$y;$xfDoes not work for obvious reasons but it is POSIX or sh compliant.\n"
y=12
printf "%b" "\x1B[""$y"';'"$x""fWorks but is POSIX and sh compliant...\n"
y=14
# Why is line 5 not posix complaint but line 18 is?
printf "%b" "\x1B["$y';'$x"fWorks but is POSIX and sh compliant...\n"
exit 0

Results from 'ShellCheck':-
Code:
$ shellcheck myscript
 
Line 5:
printf "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
       ^-- SC2059: Don't use variables in the printf format string. Use printf "..%s.." "$foo".
              ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
                   ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
 
Line 7:
printf "%b" "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
                   ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
                        ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
 
Line 13:
printf "%b" "\x1B[$y;$xfDoes not work for obvious reasons but it is POSIX and sh compliant.\n"
                     ^-- SC2154: xfDoes is referenced but not assigned.

$

Now line 13 is obviously wrong so ignore that but why is line 5 NOT posix compliant but line 18 IS compliant?
Most of the AudioScope.sh printf statements follow the line 9 format...
Terminal results; OSX 10.7.5, default terminal calling 'sh'.
Code:
       Works but is not POSIX or sh compliant...

       Works but is not POSIX or sh compliant...

       Works but is POSIX and sh compliant...

       Works but is POSIX and sh compliant...
ot work for obvious reasons but it is POSIX or sh compliant.


       Works but is POSIX and sh compliant...

       Works but is POSIX and sh compliant...
AMIGA:barrywalker~/Desktop/Code/Shell> _

TIA...
# 9  
Old 06-11-2016
In line 5 the expansions $x and $y are not quoted. If the expansion of $x or $y contains any IFS field separator characters, your format string argument to printf will terminate at the 1st whitespace character in the resulting set of strings passed to printf by the shell after the shell expands those variables.

When a variable name in a variable expansion is followed by characters that could be part of a variable name, use:
Code:
"${variable}other text"

instead of:
Code:
"$variableother text"

You don't have to quote and unquote every reference to a variable in a quoted string. The following all have exactly the same results in a shell script:
Code:
"$v1 $v2 ${v3}text"
"$v1"" ""$v2"" ""${v3}""text"
"$v1"" ""$v2"" ""$v3""text"
"$v1"' '"$v2"' '"${v3}"'text'
"$v1"' '"$v2"' '"$v3"'text'

The normal way to write the printf command:
Code:
printf "%b" "\x1B["$y';'$x"fWorks but is POSIX and sh compliant...\n"

even though the above will not do what you want if $y or $x expands to a string containing any whitespace characters (since both expansions are unquoted), is:
Code:
printf '\x1B[%s;%sfWorks and is POSIX and sh compliant...\n' "$y" "$x"

which will work correctly even if $x and $y expand to strings that contain percent signs and/or whitespace characters.
This User Gave Thanks to Don Cragun For This Post:
# 10  
Old 06-12-2016
Thank you Don...

Your explanation is thorough and finding this sort of information on the WWW is near impossible.

It looks lke I will have to go through the AudioScope code again and clean up. There are only a few lines that contain variables to be expanded.
(BTW I meant to quote line 7 and line 18 - NOT 5. Humble apologies...)
Code:
I still don't quite understand why ShellCheck rejects:-
printf "%b" "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
But accepts:-
printf "%b" "\x1B["$y';'$x"fWorks but is POSIX and sh compliant...\n"

The only difference is ";" and ';' .
Quote:
even though the above will not do what you want if $y or $x expands to a string containing any whitespace characters (since both expansions are unquoted), is:
I would probably never have found this as 'x' and 'y' will always be integers.
Once again you have put me on the straight and narrow.
Finally, do I assume that the line below is not a valid posix 'printf' statement as it is lacking the '%b'?
Code:
 printf "\x1B[0;34;43mIs this a valid posix compliant line?"

It does work in 'sh' on this MBP, OSX 10.7.5 default terminal running sh.
(It seems '%b' is a default modifier for 'printf'.)
Finally thanks again...
# 11  
Old 06-12-2016
Quote:
Originally Posted by wisecracker
Thank you Don...

Your explanation is thorough and finding this sort of information on the WWW is near impossible.

It looks lke I will have to go through the AudioScope code again and clean up. There are only a few lines that contain variables to be expanded.
(BTW I meant to quote line 7 and line 18 - NOT 5. Humble apologies...)
Code:
I still don't quite understand why ShellCheck rejects:-
printf "%b" "\x1B["$y";"$x"fWorks but is not POSIX or sh compliant...\n"
But accepts:-
printf "%b" "\x1B["$y';'$x"fWorks but is POSIX and sh compliant...\n"

The only difference is ";" and ';' .
I will make the wild assumption that ShellCheck is just checking the printf utility format string operand (and perhaps checking that there are enough operands supplied to match %format-specifier and * in %*.*format-specifier occurrences in the format string operand). Since a format string can be reused if more operands are present than format specifiers, it would be a lot harder for it to determine when an unquoted shell variable is expanded in an operand is wrong versus when an unquoted shell variable in a format string could cause early termination of the format string.
Quote:
I would probably never have found this as 'x' and 'y' will always be integers.
Once again you have put me on the straight and narrow.
Finally, do I assume that the line below is not a valid posix 'printf' statement as it is lacking the '%b'?
Code:
 printf "\x1B[0;34;43mIs this a valid posix compliant line?"

It does work in 'sh' on this MBP, OSX 10.7.5 default terminal running sh.
(It seems '%b' is a default modifier for 'printf'.)
Finally thanks again...
No. There is nothing wrong with this this printf command (other than the fact that it won't do what you want on a machine using an EBCDIC codeset and will only work on certain output devices that understand the escape sequence you have encoded at the start of that output). There are no variables in that format string that could be expanded to require additional operands. That command (with double-quotes as you used them or with the double-quotes replaced by single-quotes) produces a partial line of output that is perfectly well-formed. And, since that format string operand contains no percent sign characters, the following commands would also be valid commands producing exactly the same output (more slowly):
Code:
printf '%s' '\x1B[0;34;43mIs this a valid posix compliant line?'
printf '%s' '\x1B[0;34;43mIs this a valid posix compliant line?'

(and, in both of those commands the 1st two single-quotes can be changed to double-quotes and the last two single-quotes can be changed to double-quotes with no difference in the output (but it will run slightly more slowly)).

Last edited by Don Cragun; 06-12-2016 at 06:47 AM.. Reason: PS removed; it wasn't in the standards even though it would work on some systems.
This User Gave Thanks to Don Cragun For This Post:
# 12  
Old 06-12-2016
(Bringing it back to the title.)

Hi Don et al...

Since you guys have given valid crticism of AudioScope.sh it has made me look more deeply into posix compliance, so......

I typed this directly into ShellCheck and got the bizarre results below.
It means I have to check absolutelty everything from variable constructs to printing to 'STDOUT'.
It looks like ShellCheck successfully finds any variables that seem unused; however...
Ignore the printf STDOUT printing _errors_ that could be produced as I am now fully aware of those...
Code:
#!/bin/sh
x='A string.'
y='Another string.'
text='\x1B[0m'$y' '$x'These variables look OK!'
texts="1x1B[0m"$y' '$x"These variables look OK too!."
txt='\x1B[0m'$y" "$x'These variables look OK also!'
txts="\x1B[0m"$y" "$x"This is bizarre, why the inverted commas error?"

Code:
$ shellcheck myscript
 
Line 4:
text='\x1B[0m'$y' '$x'These variables look OK!'
^-- SC2034: text appears unused. Verify it or export it.
 
Line 5:
texts="1x1B[0m"$y' '$x"These variables look OK too!."
^-- SC2034: texts appears unused. Verify it or export it.
 
Line 6:
txt='\x1B[0m'$y" "$x'These variables look OK also!'
^-- SC2034: txt appears unused. Verify it or export it.
 
Line 7:
txts="\x1B[0m"$y" "$x"This is bizarre, why the inverted commas error?"
^-- SC2034: txts appears unused. Verify it or export it.
              ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
                   ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.

$

I have made a rod for my own back here...

Thanks to Don all for your input...
# 13  
Old 06-12-2016
Hi wisecracker,
There are lots of things to consider here. Strings used in variable assignments follow slightly different rules than strings used in other shell operations (such as command-line arguments to utilities). See the following script for example:
Code:
#!/bin/sh
a=" after"
b="before "
m=" middle "
x=' a b '
y=' echo d '
unset v1 v2
# Note that the expandsion of $y and $x in the next statement are not quoted.
v1="before"$y" "$x"after"
printf '"v1":X%sX\n' "$v1"
printf 'v1:X%sX\n' $v1

# Note that the strings to which $y and $x are substituted here, but not as
# variable expansions.  Here "echo" becomes a command to execute with v2 set as
# a variable in the environment of the echo command, but it is not set in the
# current shell execution environment.
v2="before" echo d " " a b "after"
printf '"v2":X%sX\n' "$v2"
printf 'v2:X%sX\n' $v2

# Now see how those same sets of strings are handled when passed as arguments to
# a utility instead of being assigned to a variable...
printf 'v1string:X%sX\n' "before"$y" "$x"after"
printf 'v2string:X%sX\n' "before" echo d " " a b "after"

# Spaces still matter when variable expansions are separated by IFS characters.
set -xv
w=$b $m $a
z=$b$m$a
set +xv
# And, of course leading and trailing spaces disappear when fields are separated
# in unquoted arguments.
printf 'space between:X%sX\n' $b $m $a
printf 'no space between:X%sX\n' $b$m$a

which produces the output:
Code:
"v1":Xbefore echo d   a b afterX
v1:XbeforeX
v1:XechoX
v1:XdX
v1:XaX
v1:XbX
v1:XafterX
d   a b after
"v2":XX
v2:XX
v1string:XbeforeX
v1string:XechoX
v1string:XdX
v1string:X X
v1string:XaX
v1string:XbX
v1string:XafterX
v2string:XbeforeX
v2string:XechoX
v2string:XdX
v2string:X X
v2string:XaX
v2string:XbX
v2string:XafterX
w=$b $m $a
+ w='before '
+ middle after
tester: line 28: middle: command not found
z=$b$m$a
+ z='before  middle  after'
set +xv
+ set +xv
space between:XbeforeX
space between:XmiddleX
space between:XafterX
no space between:XbeforeX
no space between:XmiddleX
no space between:XafterX

So, in your statement:
Code:
txts="\x1B[0m"$y" "$x"This is bizarre, why the inverted commas error?"

it does what you want even though the expansions $y and $x are not quoted (because it is an assignment statement). But, why are you adding the extra double-quotes? They don't do anything but make the code harder to read. Variable expansions, command substitutions, and arithmetic expansion are all processed in double-quoted strings, so why not simplify your code and make it easier to read and understand:
Code:
txts="\x1B[0m$y ${x}This is bizarre, why the inverted commas error?"

(which is a single double-quoted string). Or, if you are really against using braces to keep variable names separate from following text:
Code:
txts='\x1B[0m'"$y $x"'This is bizarre, why the inverted commas error?'

(which has the constant characters in the two single-quoted strings and the variable expansions in a single double-quoted string).
And, besides being easier to read and understand, I would think either of these should make shellcheck happy too. (But I don't have shellcheck installed on my system; so I haven't verified that.)

I should also have mentioned in earlier posts on this subject that \x followed by two hexadecimal digits is a common extension provided by many implementations of the printf utility (both stand-alone and as shell built-ins), but it is not mentioned in the standards. Similarly, \e is a common extension that expands to an escape character in the current locale provided by many implementations of the printf utility, but it is not mentioned in the standards either. With any standards conforming version of printf, you can use the octal escape sequence \033 to specify an escape character in locales with an underlying codeset that is a superset of ASCII.
# 14  
Old 06-13-2016
Quote:
Originally Posted by wisecracker
Code:
txts="\x1B[0m"$y" "$x"This is bizarre, why the inverted commas error?"
^-- SC2034: txts appears unused. Verify it or export it.
              ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
                   ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.
$

This may help:

Code:
     +-------+  +-+  +-----------------------------------------------+
     v       v  v v  v                                               v
txts="\x1B[0m"$y" "$x"This is bizarre, why the inverted commas error?"

The shell maintains only a single switch for "inside a quoted string" which can be true or false. Therefore it is not possible to nest any quotations. We have often the misunderstanding here that it works like this:

Code:
+-----------------+
|    +------+     |
v    v      v     v
"    '      '     "

That is: a single-quoted string inside a double-quoted string. The truth is it is like this:

Code:
+-----------------+
v                 v
"    '      '     "

because the single-quotes lose their special meaning as quoting characters inside a quoted string. The shell, upon encountering the first double quote, flips its flag to "inside a quoted string" and it takes every character literally until encountering the second double-quote, when it flips the flag back to "outside a quoted string".

There is actually only a single exception to this rule and it happens with subshells:

Code:
echo "foo$(command "arg1" "arg2")bar"

is actually one double-quoted string "foo<something>bar", where <something> is the output of the command command "arg1" "arg2".


One more word about your escape-sequences: You might make your script a lot more flexible by using the respective terminals escape-queneces instead of using fixed ones. I haven't looked up what \x1B[0m is for, but lets suppose it is for moving the cursor to row 0, col 0. A better way would be to do it like this:

Code:
chHome="$(tput home)"          # query TERMINFO database for sequence to home cursor

[...]
printf "%sThis text starts in left upper corner.\n" "$chHome"


I hope this helps.

bakunin

Last edited by bakunin; 06-13-2016 at 03:59 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Solaris

Solaris 10: how to disable an unused HBA card

Dear all, I have a new Oracle Blade X4-2B server, running Solaris 10. The server comes with a HBA card that will not be used now. It has not fibers connected to it. As a consequence, its leds never stop flashing. My question is: how to disable this HBA card, without removing it physically... (2 Replies)
Discussion started by: Gus1971
2 Replies

2. Programming

What Unix do with unused shared memory?

Hello, When creating shared memory in C, should be remove shared memory with shmctl function when don't need it. If it didn't remove, occupied shared memory stay and remain. If we create shared memory repeatedly without removing unusable shared memory, /dev/shm will full. Does Unix or... (1 Reply)
Discussion started by: pronetin
1 Replies

3. AIX

Temporarily disabling unused ethernet adapter

Hi, In our AIX 5.2 server , we have one unused ethernet adapter which doesn't have cable connection . For this interface , we are getting alerts in errpt . Could you suggesthow to stop this alert ? And sametime i would like to keep this device in ODM . Is there... (1 Reply)
Discussion started by: sekarsamy
1 Replies

4. Solaris

unused disk space

i Have alloted 20G in my vmware for solaris 10, upon installation, and some distribution of disk space to /,/opt,swap i just use 19G. Can i still use the 1G? How? how to see the 1G? that i did not use? how can i use it? appreciate your responce (17 Replies)
Discussion started by: kenshinhimura
17 Replies

5. HP-UX

HP-UX using unused HDD space

Hello, I have a system with HP-UX 11.23 installed on it. There are ~36GB of unused space on the HDD. I did a very basic installation, and it created the usual volume group /dev/vg00. When I look at the output of ioscan -funC disk, I see this (and more, but irrelevant to this post): disk ... (1 Reply)
Discussion started by: goon12
1 Replies

6. AIX

how to clean Unused semaphore??

How can i clean up my unused semaphore??? (4 Replies)
Discussion started by: abhishek27
4 Replies

7. UNIX for Dummies Questions & Answers

delete the unused file

Hi All, Can you please let me know how to delete any files that have not been accessed in the past 28 days in a directory. Thanks, Arun (3 Replies)
Discussion started by: arunkumar_mca
3 Replies

8. AIX

unused storage on AIX 4.3

Hi, How do I query for unused partition in AIX 4.3 with DAS and SAA storage? I know most unix administrator don't put all the capacity on the system at once. thanks, vene (1 Reply)
Discussion started by: venerayan
1 Replies

9. UNIX for Dummies Questions & Answers

How do I get the unused space?

One of my Solaris 8 machines hd was about to die. So I used g4u to create an image of the 9gb drive and I put it in a 36gb drive. That solved my dieing hd problem. But.... How do I get my machine to see the unused 27gb of space? Any help would be greatly appreciated. (1 Reply)
Discussion started by: Spyzic
1 Replies
Login or Register to Ask a Question