Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

For /F loops

799 views
Skip to first unread message

DanS

unread,
Dec 27, 2013, 10:41:57 AM12/27/13
to
Unfortunately, I've gotten involved in a "scripting challenge" with a Linux user. I'm trying
to replicate what he had written in BASH to run on Linux, in CMD batch to run in
Windows. Essentially, it lists a bunch of OS and hardware info.

I'm trying to enumerate user groups, currently using a Windows7 PC.

I want to use this cli command...

\wmic group get name

...in a batch file.

When I have a batch file containing...
--------------------------------------------------------------------------------
@echo off
setlocal

for /F %%a IN ('wmic group get name') DO echo. Group: %%a
--------------------------------------------------------------------------------

...this 'works'.

However, If I try to do this...

--------------------------------------------------------------------------------
@echo off
setlocal

for /F %%a IN ('wmic group get name') DO (
SET GROUP=%%a
echo Group: %GROUP%
)
--------------------------------------------------------------------------------

This "doesn't work", and appears that %GROUP% is NEVER set to %%a at any time.
I can add echo %%a as the last line under echo %GROUP%, and %%a is echo'd
properly

THIS IS THE PROBLEM. If I can get %%a in to %GROUP%, I can manage from there.

FWIW, I ran into a similar issue when trying to do

\wmic nicconfig get ipaddress
\wmic nicconfig get ipsubnet

These all return more than one line. Is this the cause of the problem?

(Yes, I was using delims= as well as token= , and was able to see the 'right' info if I
echo'd %%a directly following the DO, but I just can't seem to get %%a into another
variable to enable further processing!!)

I'm sure I'm missing some minute detail trying to do all of this.

Thanks in advance,

DanS

JJ

unread,
Dec 27, 2013, 12:38:43 PM12/27/13
to
[snip]

You'll need to understand that whatever follows the FOR command, are FOR's
parameters and any specified environment variables will be immediately
expanded by the interpreter.

So this command:

set z=XYZ
FOR %%a in (a b c) DO (
set z=%%a
echo [%z%]
)

The FOR command will be interpreted as:

FOR %%a in (a b c) DO ((set z=%%a) & (echo [%z%]))

Then:

FOR %%a in (a b c) DO ((set z=%%a) & (echo [XYZ]))

So, the environment variable on ECHO's parameter is already expanded when
the ECHO command is executed.

For this, you'll need the SETLOCAL's ENABLEDELAYEDEXPANSION parameter and
use "!" instead of "%" to specify environment variables.

@echo off
setlocal enabledelayedexpansion

for /F %%a IN ('wmic group get name') DO (
set GROUP=%%a
echo Group: !GROUP!
)

Frank P. Westlake

unread,
Dec 27, 2013, 12:41:17 PM12/27/13
to
On 12/27/2013 07:41 AM, > @echo off
> setlocal
>
> for /F %%a IN ('wmic group get name') DO (
> SET GROUP=%%a
> echo Group: %GROUP%
> )
>
--------------------------------------------------------------------------------
>
> This "doesn't work", and appears that %GROUP% is NEVER set to %%a at
any time.

> I'm sure I'm missing some minute detail trying to do all of this.

The minute detail is that the whole FOR block "FOR ... (...)" is read at
once and all environment variables are expanded at that time, and all
that occurs before GROUP is set to %%a. So when you echo the group you
are echoing whatever GROUP was set to before that FOR block was read,
which was probably nothing.

SOLUTION
Use delayed expansion:

setlocal ENABLECOMMANDEXTENSIONS ENABLEDELAYEDEXPANSION

for /F %%a IN ('wmic group get name') DO (
SET GROUP=%%a
echo Group: %GROUP%
)

I don't have Windows so I can't check for typos in the above.

Frank

frank.w...@gmail.com

unread,
Dec 27, 2013, 2:35:40 PM12/27/13
to
From "Frank P. Westlake" :
>SOLUTION
>Use delayed expansion:

> setlocal ENABLECOMMANDEXTENSIONS
>ENABLEDELAYEDEXPANSION

> for /F %%a IN ('wmic group get name') DO (
> SET GROUP=%%a
> echo Group: %GROUP%
> )

>I don't have Windows so I can't check for typos in the
>above.

Oops! I forgot to replace the percent signs.

for /F %%a IN ('wmic group get name') DO (
SET GROUP=%%a
echo Group: !GROUP!
)

Frank

Petr Laznovsky

unread,
Dec 27, 2013, 2:54:32 PM12/27/13
to
Dne 27.12.2013 18:41, Frank P. Westlake napsal(a):
Should not be ENABLEEXTENSIONS instead of ENABLECOMMANDEXTENSIONS??

L.

DanS

unread,
Dec 27, 2013, 7:19:02 PM12/27/13
to
frank.w...@gmail.com wrote in news:1433590f56b$frank.w...@gmail.com:
Thanks to all that responded. As I thought, it was a minute detail.

I should hve been able to figure this out. I had to use setlocal enabledelayedexpansion
for the last BASH vs. CMD challenge, but that was for nested variables, and it just
didn't click this time.

One further question however....

...in my OP, I mentioned this was a problem when trying to parse the return from...

\wmic nicconfig get ipaddress

...as well.

This command receives multi-line responses no matter how many IPs are assigned.

I'd like to report multiple IPs, if multiple are assigned, but I was having trouble parsing
the return data, because it returns a lot of nothing, could be just cr/lf's, before returning
the actual IP assigned.

for /F "tokens=2 delims==" %%a IN ('wmic nicconfig get ipaddress') DO (
SET IP=%%a
echo Address: !IP!
)

If you run: wmic nicconfig get ipaddress from a cmd line, you get a lot of blank lines,
then the IP address at the end.

I was trying to detect the blank lines, so I could just print out/process the assigned IP
address(es) as necessary.

Even before using the ! instead of %, this didn't seem to work..

for /F "tokens=2 delims==" %%a IN ('wmic nicconfig get ipaddress') DO if [%%a]=[]
echo Address: %%s



Thanks in advance, again,



DanS


foxidrive

unread,
Dec 27, 2013, 7:43:10 PM12/27/13
to
On 28/12/2013 11:19, DanS wrote:
> \wmic nicconfig get ipaddress
>
> ....as well.
>
> This command receives multi-line responses no matter how many IPs are assigned.
>
> I'd like to report multiple IPs, if multiple are assigned, but I was having trouble parsing
> the return data, because it returns a lot of nothing, could be just cr/lf's, before returning
> the actual IP assigned.
>
> for /F "tokens=2 delims==" %%a IN ('wmic nicconfig get ipaddress') DO (
> SET IP=%%a
> echo Address: !IP!
> )
>
> If you run: wmic nicconfig get ipaddress from a cmd line, you get a lot of blank lines,
> then the IP address at the end.
>
> I was trying to detect the blank lines, so I could just print out/process the assigned IP
> address(es) as necessary.
>
> Even before using the ! instead of %, this didn't seem to work..
>
> for /F "tokens=2 delims==" %%a IN ('wmic nicconfig get ipaddress') DO if [%%a]=[]
> echo Address: %%s

Wmic returns Unicode, trailing space, appended carriage returns, and it's a cow to parse at times.

See if this helps.

@echo off
for /f "tokens=2,3 delims={,}" %%a in ('
"WMIC NICConfig where IPEnabled="True" get IPAddress /value | find "I" "
') do echo IPv4 %%~a IPV6 %%~b
pause


This shows some extra info that can be accessed.

@echo off
WMIC NICConfig where "IPEnabled='True'" get Description, IPAddress, IPSubnet, DefaultIPGateway
/value|FIND "="
pause


Petr Laznovsky

unread,
Dec 28, 2013, 1:00:49 AM12/28/13
to DanS
Dne 28.12.2013 1:19, DanS napsal(a):
Maybe you want to limit WMIC output to physical network adapters only (reduce empty lines on output):

where "NOT Manufacturer = 'Microsoft' AND NOT PNPDeviceID LIKE 'ROOT\\%' AND (ConfigManagerErrorCode
= 0 OR (ConfigManagerErrorCode = 22 AND NetConnectionStatus = 0))"

L.

BTW: Do not forget doubled percent sign in case to put where clause to variable

frank.w...@gmail.com

unread,
Dec 28, 2013, 3:26:50 AM12/28/13
to
From DanS :
>One further question however....
>...in my OP, I mentioned this was a problem when trying
>to parse the return from...
>\wmic nicconfig get ipaddress
>...as well.

>I was trying to detect the blank lines, so I could just
>print out/process the assigned IP
>address(es) as necessary.

WMIC prints an extra carraige return (\r\r\n); my guess
is that this is to preserve blank lines. To avoid them
you need only check that the variable is not empty after
being set from the token, because the final \r\n is
stripped when the token is created and the remaining \r
is lost on the SET command line. For example:

FOR /F %%a in ('wmic ...') do (
SET "var=%%a"
IF "!var!" NEQ "" (
REM Process 'var'.
)
)

Frank

foxidrive

unread,
Dec 28, 2013, 4:04:04 AM12/28/13
to
On 28/12/2013 19:26, frank.w...@gmail.com wrote:

> WMIC prints an extra carraige return (\r\r\n); my guess
> is that this is to preserve blank lines. To avoid them
> you need only check that the variable is not empty after
> being set from the token, because the final \r\n is
> stripped when the token is created and the remaining \r
> is lost on the SET command line. For example:

No it's not, Frank. the \r has to be removed.

I tested Wmic with the command from this thread and there were no extra appended CR
I CBF checking other commands to see if it's fixed in Win 8.1 but I suspect it's not and that WMIC does
different things with different commands.



DanS

unread,
Dec 28, 2013, 10:04:27 AM12/28/13
to
foxidrive <foxi...@server.invalid> wrote in
news:52be1ea0$0$10302$c3e8da3$9b4f...@news.astraweb.com:
Thank you.

The former snippet you offered works great, with one caveat. If the PC has more than
one IPv4 IP address assigned, they are all printed in succession before the IPv6
address.

I removed the echoing of IPv4 and IPv6, and added ,IPSubnet to it, and added another
var to echo...

@echo off
for /f "tokens=2-4 delims={,}" %%a in ('
"WMIC NICConfig where IPEnabled="True" get IPAddress, IPSubnet /value
| find "I" " ') do echo %%~a %%~b %%~c
pause


This output results in:

192.168.0.254 10.10.10.10 fe80::9c91:1eb7:a3bc:4fba
255.255.255.0 255.255.255.0 64


So I see 2 v4 IPs followed by one v6 IP space delimited.
And then 2 v4 SNMs, followed by the v6 SNM, assuming they correlate to each other in
series, the first IP/first subent, etc.

...now to try to step through those and place them properly.


It seems like in CMD there's a lot of little caveats.......like why is the delims= enclosed
in { }'s?.....and why the ~ before the var, like %%~a?

I wish I would have done a little more CMD scripting back when, rather than mainly just
batching simple app startup routines and the like.

Thanks again for your help.

Regards,

DanS










foxidrive

unread,
Dec 28, 2013, 11:17:15 AM12/28/13
to
On 29/12/2013 02:04, DanS wrote:
> The former snippet you offered works great, with one caveat. If the PC has more than
> one IPv4 IP address assigned, they are all printed in succession before the IPv6
> address.
>
> I removed the echoing of IPv4 and IPv6, and added ,IPSubnet to it, and added another
> var to echo...
>
> @echo off
> for /f "tokens=2-4 delims={,}" %%a in ('
> "WMIC NICConfig where IPEnabled="True" get IPAddress, IPSubnet /value
> | find "I" " ') do echo %%~a %%~b %%~c
> pause
>
>
> This output results in:
>
> 192.168.0.254 10.10.10.10 fe80::9c91:1eb7:a3bc:4fba
> 255.255.255.0 255.255.255.0 64
>
>
> So I see 2 v4 IPs followed by one v6 IP space delimited.
> And then 2 v4 SNMs, followed by the v6 SNM, assuming they correlate to each other in
> series, the first IP/first subent, etc.

Yes, I see.

> ...now to try to step through those and place them properly.
>
>
> It seems like in CMD there's a lot of little caveats.......like why is the delims= enclosed
> in { }'s?.....and why the ~ before the var, like %%~a?

if you execute the code from a cmd prompt you will see the extra characters delimiting the entries, and
the { } and , are removed by the delims portion: try this:

WMIC NICConfig where IPEnabled="True" get IPAddress, IPSubnet /value

In %%~a the plain tilda cause it to remove the surrounding quotes from the token. You'll notice them in
the verbose list too.

> I wish I would have done a little more CMD scripting back when, rather than mainly just
> batching simple app startup routines and the like.
>
> Thanks again for your help.

You're welcome, glad I could help.

foxi

DanS

unread,
Dec 28, 2013, 11:25:15 AM12/28/13
to
foxidrive <foxi...@server.invalid> wrote in
news:52bef98d$0$10329$c3e8da3$9b4f...@news.astraweb.com:
DOH! I thought the {} had some other esoteric meaning!!!

They are just used as DELIMS!!!!


>
> WMIC NICConfig where IPEnabled="True" get IPAddress,
> IPSubnet /value
>
> In %%~a the plain tilda cause it to remove the surrounding
> quotes from the token. You'll notice them in the verbose
> list too.

Yes, I did. The return was {"192.168.0.254"}

I was using a substring call to remove the leading and trailing {" "}.

Good to know there's a 'built-in' way.



>
>> I wish I would have done a little more CMD scripting back
>> when, rather than mainly just batching simple app startup
>> routines and the like.
>>
>> Thanks again for your help.

...and yet again.



>
> You're welcome, glad I could help.

It is greatly appreciated.

>
> foxi

Regards,

DanS

DanS

unread,
Dec 28, 2013, 11:26:42 AM12/28/13
to
foxidrive <foxi...@server.invalid> wrote in
news:52be9406$0$10315$c3e8da3$9b4f...@news.astraweb.com:
Of course it does.....we can't have a consistantly formatted output no matter what the
return data now, can we?

[/sarcasm]


big_jon...@lycos.co.uk

unread,
Dec 28, 2013, 1:04:48 PM12/28/13
to
On Friday, 27 December 2013 15:41:57 UTC, DanS wrote:
> Unfortunately, I've gotten involved in a "scripting challenge" with a Linux user. I'm trying
>
> to replicate what he had written in BASH to run on Linux,
>

I would suggest that you forget trying to compete using the inferior cmd.exe console and use the much more powerful powershell console.

DanS

unread,
Dec 29, 2013, 11:22:34 AM12/29/13
to
foxidrive <foxi...@server.invalid> wrote in
news:52bef98d$0$10329$c3e8da3$9b4f...@news.astraweb.com:
So I've done some more work on this IP Address setting(s), and have a couple more
questions.

This is what I came up with using wmic, and not |'g through the find command to get a
comma-delimited lists of IP addresses.

------------------------------------------------------------------------------------------
@echo off
setlocal
setlocal enabledelayedexpansion
setlocal enableextensions

FOR /F "tokens=2 delims={=}" %%a IN ('wmic nicconfig get ipaddress /value') DO (
SET IP=%%a
SET IP=!IP:~4,1!
IF DEFINED IP SET IP=%%a
)

echo.
echo IPs: !IP!
echo.

FOR /F "tokens=1-10 delims=, " %%a IN ("!IP!") DO (
echo IP Address: %%~a
echo IP Address: %%~b
IF NOT "%%c"=="" echo IP Address: %%~c
IF NOT "%%d"=="" echo IP Address: %%~d
IF NOT "%%e"=="" echo IP Address: %%~e
)

goto :eof
----------------------------------------------------------------------------------------------

Running this will print out one blank line, the complete returned comma delimited IPs,
and then a line below for each IP Address assigned. Of course, if yo only have one IP
address, as above %%~b will still print an empty line, because I'm not checking to see
if it's DEFINED.

In the top half, without the |'d find, I'm just checking to see if theres a 4th char before
assigning %%a to %IP%. In the bottom half, I am parsing that returned line, and
displaying it.

The questions are:

1) The bottom loop where it displays, is there any way to know how many of 1-10
tokens were returned w/o checking them individually as I did above? I'm looking for the
'cleanest' looking code. I'm used to working in a vaierty of BASICs, VC++ and several
c-based embedded processor languages.

2) Changing the token=1-10 to tokens=1*, because we don't know how many IPs are
assigned, the IF NOT "%%c"=="", and on, does not work properly, and it echos:

IP Address: %~c
IP Address: %~d
IP Address: %~e

...if there isn't a returned token, rather than the %%c,d,e 's being seen to == [ ].

Thank you once again in advance.

Regards,

DanS













foxidrive

unread,
Dec 29, 2013, 11:37:57 AM12/29/13
to
On 30/12/2013 03:22, DanS wrote:

> So I've done some more work on this IP Address setting(s), and have a couple more
> questions.
>
> This is what I came up with using wmic, and not |'g through the find command to get a
> comma-delimited lists of IP addresses.
>
> ------------------------------------------------------------------------------------------
> @echo off
> setlocal
> setlocal enabledelayedexpansion
> setlocal enableextensions

Each of those setlocals is a separate environment.
Just use one, in this format is you need the extensions.

setlocal enabledelayedexpansion enableextensions


> FOR /F "tokens=2 delims={=}" %%a IN ('wmic nicconfig get ipaddress /value') DO (
> SET IP=%%a
> SET IP=!IP:~4,1!
> IF DEFINED IP SET IP=%%a
> )
>

I'm not sure what you want to do with the set of IPs but this will give you just the list of lines with
an IP in them:


wmic nicconfig get ipaddress /value|find "."


foxidrive

unread,
Dec 29, 2013, 11:39:48 AM12/29/13
to
It occurs to me that you may only have an IPv6 so use this instead:

wmic nicconfig get ipaddress /value|find "{"

DanS

unread,
Dec 29, 2013, 11:53:10 AM12/29/13
to
foxidrive <foxi...@server.invalid> wrote in
news:52c05056$0$10264$c3e8da3$9b4f...@news.astraweb.com:
I'd like to recieve the list of IPs, a list of Subnet masks, and concatenate them together
to display as

IP Address(es): 192.168.0.254/255.255.255.0
10.10.10.1/255.255.255.252
10.10.23.12/255.255.0.0

...getting the list of IP and SNMs isn't the problem now. The problem is handling the
variable number of IP addresses/SNMs that may be assigned/returned, as per my
outlined questions in my previous post.


Thanks again.

foxidrive

unread,
Dec 29, 2013, 6:51:57 PM12/29/13
to
On 30/12/2013 03:53, DanS wrote:
> I'd like to recieve the list of IPs, a list of Subnet masks, and concatenate them together
> to display as
>
> IP Address(es): 192.168.0.254/255.255.255.0
> 10.10.10.1/255.255.255.252
> 10.10.23.12/255.255.0.0
>
> ....getting the list of IP and SNMs isn't the problem now. The problem is handling the
> variable number of IP addresses/SNMs that may be assigned/returned, as per my
> outlined questions in my previous post.


Try this out:

@echo off
set "file1=%temp%\filea"
set "file2=%temp%\fileb"
del "%file1%" "%file2%" 2>nul

for /f "tokens=1,2 delims=={," %%a in ('wmic nicconfig get ipaddress /value^|find "{"') do >>%file1% echo
%%~b
for /f "tokens=1,2 delims=={," %%a in ('wmic nicconfig get ipsubnet /value^|find "{"') do >>%file2% echo %%~b

set num=0
setlocal EnableDelayedExpansion
< "%file2%" (
for /F "usebackq delims=" %%a in ("%file1%") do (
set file2Line=
set /P file2Line=
set "file1Line=%%a"
set /a num+=1
if not "!file1Line:.=!"=="!file1Line!" set IP[!num!]=!file1Line!/!file2Line!
)
)
del "%file1%" "%file2%" 2>nul
set ip
pause

foxidrive

unread,
Dec 29, 2013, 7:05:12 PM12/29/13
to
On 30/12/2013 10:51, foxidrive wrote:
> On 30/12/2013 03:53, DanS wrote:
>> I'd like to recieve the list of IPs, a list of Subnet masks, and concatenate them together
>> to display as
>>
>> IP Address(es): 192.168.0.254/255.255.255.0
>> 10.10.10.1/255.255.255.252
>> 10.10.23.12/255.255.0.0
>>
>> ....getting the list of IP and SNMs isn't the problem now. The problem is handling the
>> variable number of IP addresses/SNMs that may be assigned/returned, as per my
>> outlined questions in my previous post.
>
>
> Try this out:

This might work the same - with simpler code.

@echo off
setlocal EnableDelayedExpansion
set "ip="
set "snm="
set "num=0"

for /f "tokens=1,2 delims=={," %%a in ('
" wmic nicconfig get ipaddress, ipsubnet /value |find "{" "
') do (
if defined ip if not defined snm set snm=%%~b
if not defined ip set ip=%%~b
if defined ip if defined snm (
set /a num=num+1
set IP[!num!]=!ip!/!snm!
set "ip="
set "snm="
)
)

set ip
pause




DanS

unread,
Jan 2, 2014, 7:44:40 PM1/2/14
to
foxidrive <foxi...@server.invalid> wrote in
news:52c0b8ba$0$10328$c3e8da3$9b4f...@news.astraweb.com:
I haven't got back to this yet.......(just lettng you know).

DanS

unread,
Jan 2, 2014, 8:13:44 PM1/2/14
to
big_jon...@lycos.co.uk wrote in
news:bb99bb8b-096f-4360...@googlegroups.com:
Well..........as I said, someone challenged me to duplicate the functionality of a BASH
script they wrote in CMD batch.

That's the only reason I am doing this. I participate in one of the newsgroups for a
particular Linux distro.

There is a recently converted guy there that drank al lthe Linux Kool-Aid, rather quickly.

This is all fine and dandy, however, like the other diehard Linux users, he immediately
started to deride all things Microsoft.

The first script he wrote simply copied the structure of a DVD to a desktop folder
named after the DVD label. He thought this was 'the sh*t', and when I told him this is
uber-basic stuff, he challenged me to see my powershell version of the same thing. I
did it in CMD batch however, because it was, super easy. If I was needing to do this for
myself, I'd just go .vbs.

I kept telling this guy that you can't put down Windows because it doesn't do something
because you don't know that it does something because you have never tried. It's like
saying "I prefer Fords, because Fords come with wheels." Well....all cars have wheels,
so, that point is invalid....at least, that what I learned in debate in HS.

I mean, this sounds logical to me.....if you have no knowledge of something, you can't
effectively put forth an opinion on it either way. Unfortunately, the most vocal persons,
don't seem to agree.












DanS

unread,
Jan 2, 2014, 8:40:06 PM1/2/14
to
foxidrive <foxi...@server.invalid> wrote in
news:52c0b8ba$0$10328$c3e8da3$9b4f...@news.astraweb.com:
I forgot to mention this in the last post where I replied to big_jonne1.....

....after I did the first script that simply copied the DVD structure, the one I did this for
said "all the %%'s and !!'s aren't very intuitive...my BASH script is much more
understandable and elegant".

So in this latest script, I was looking for the above to loop through multiple IP
addresses, and I said as clean looking code as I could, because, I don't know about
you, but th ebelow doesn't look very elegant.......

This is the output from his script for the NIC info when run on my Linux PC:

Network Information:
Hostname : DS-Kpc
Devic : ipv4 ipv6
eth0 : 192.168.0.2 fe80::2e0:4dff:fe96:b2ed/64
lo : 127.0.0.1 ::1/128
Gateway : 192.168.0.1

...and in order to get that printed to the screen, here is his code.....(he's parsing
ifconfig, which is nearly the same as parsing ipconfig)

---------------------------------------------------------------------------

# Networking, Devices

arr+=("$(echo -e "Device: ipv4\t\t ipv6")")
while read -r line; do
set -- $(IFS=' :' ; echo $line) # parse words on space and colon
if [ $# -gt 2 ] ; then # we have a line to work with
_wd1=$1 # save first word on line
if [ -z "$_nic" ] ; then # save first word on the line
_nic=$1
fi
case $_wd1 in # decide if we have an IP address line
inet) # yes and it is ipv4 address line
if [ "$2" = "addr" ] ; then # it is not Slackware output
_ip4=$3
else # it is Slackware output
_ip4=$2
fi
;;
inet6) # it is an IPV6 line
set -- $line # do not parse using colon.
if [ "$2" = "addr:" ] ; then # it is not Slackware output
_ip6=$3
else # it is Slackware output
_ip6=$2
fi
;;
esac
else # we hit end of a ifconfig stanza
arr+=("$(echo -e "$_nic : $_ip4\t $_ip6")")
_nic="" ; _ip4=" " ; _ip6=""
fi
done < <(ifconfig)

Gateway=$(ip route | awk '/default/ { print $3 }')
arr+=("$(echo "Gateway : $Gateway")")

--------------------------------------------------------------------------------------------

......that's just to get the IP info...not including DNS server.

It doesn't look very intuitive to me.



foxidrive

unread,
Jan 2, 2014, 10:23:36 PM1/2/14
to
On 3/01/2014 12:40, DanS wrote:

> said "all the %%'s and !!'s aren't very intuitive...my BASH script is much more
> understandable and elegant".


> .......that's just to get the IP info...not including DNS server.
>
> It doesn't look very intuitive to me.

There's a great saying I heard once that goes something like this:

Never argue with stupid people, they will drag you down to their level
and then beat you with experience.


There are better things to do than to emulate a BASH script with batch, just for the heck of it. :)

DanS

unread,
Jan 3, 2014, 5:28:46 PM1/3/14
to
foxidrive <foxi...@server.invalid> wrote in
news:52c62d39$0$34985$c3e8da3$4605...@news.astraweb.com:
Of course there is.....

Marek Novotny

unread,
Jan 20, 2014, 6:37:25 PM1/20/14
to
Well, DanS is a little more than misleading about the events that took
place. I'm the guy who challenged him to write the CMD script. I
certified with Microsoft more than a decade ago but since that time I
have not worked as a technical person. I also have about a year of Sun
Solaris experience, also from more than a decade ago. Think Solaris 2.5.

I discovered Linux not too long ago and started to post regarding my
progress on very basic things. Simple commands I'd learned, etc. And I
did this in a Linux group on Usenet. Mostly it's me being happy to make
progress on a platform that had been not previously discovered by me. So
this is all educational and adventurous at the same time.

The feedback to my n00b learning was helpful. So one day I write a bash
script that copies a DVD to my desktop and preps it for optical
manufacturing. That is to say, it copies the DVD and it removes certain
files that our clients often leave behind that they shouldn't. And this
is all done on a Mac because the Mac has the software which creates a
special type of pre-master for optical manufacturing. The Mac also has
bash and since I am learning bash it seemed a natural to do this as a
learning experience. And so I shared this with the group. What I was
doing, why and how I did it.

I mentioned that I thought Linux was pretty darn awesome and that the
script was really simple to do. A guy, such as me, with very little
experience was able to cobble together a workable script that worked out
quite nicely.

DanS here decided that mean Windows sucks. Which I never said, and have
since challenged him to find where I said such a thing. When DanS said
this could be done in CMD. I said, "Let's see it" because I believe
seeing is believing. I even went as far as to stipulate that my script
was hardly more than commands cobbled together, that I lacked experience
and that I simply wanted to see this to see if there were any weak spots
that became obvious when he duplicated the functions.

DanS likes to make this sound like I'm somehow vicious. Not at all. I
simply opined, and continue to opine, that I think bash is more elegant
and easy to read and learn than cmd. And that this is based on the
scripts he has shown me so far vs the ones I have been able to write
either on my own or with the help of others.

DanS has been nice enough to take the challenge and show me exactly what
the script would look like in cmd and it is most appreciated. Based on
what he has shown me I still hold the same opinion. DanS started the
discussion specifically with cmd, and so that is why the challenge is
regarding cmd.

He mentioned cmd yet again as myself and a small part of the group
started working on a new script that started out as me just looking for
random pieces of info about my Linux distribution. I'm sorry to say this
but if I make a positive comment about Linux DanS takes that as a
negative against Windows. I didn't even mention Windows at all when
making this script with the group. That discussion is started by DanS,
not I. I have absolutely no interest in Windows. I have years of using
it, supporting it, and I have moved on. That's not to say it is bad,
good or something else. Simply that my interests have moved on.

I don't mean or intend to invade your group or cause grief or start an
argument. Just posting my side of the event as he saw fit to mention it
here.

Thanks to those that helped DanS write the script. It has been very
educational for me and even interesting to see how such a thing could be
done in cmd.

That script in bash is currently this:

#!/bin/bash
#: Program Name : upcinfo
#: Usage : upcinfo
#: Objective : Gather Machine Info
#: Version : 3.4
#: Contributors : Bit Twister
#: Contributors : Chris Davies
#: Contributors : Jonathan N. Little
#: Contributors : Marek Novotny

# Setup
PATH=$PATH:/sbin:/usr/sbin

set -u

Version="3.4" # Removed tabs from output for better formatting control.

# Networking

_nic=""
_ip4=" "
_ip6=""

# Distribution Information

_wd1="" # word 1 of line
line="" # input line for processing
_substr="" # substring for word wraping
_rest="" # rest of the line
_tabs="" # tab characters for output
_long_line=""
_blank_col=" :"
_wrap_col=40

arr=()
Taint_Array=(
"A module with a non-GPL license has been loaded, this
includes modules with no license. Set by modutils >= 2.4.9 and
module-init-tools."
"A module was force loaded by insmod -f. Set by modutils >= 2.4.9
and module-init-tools."
"Unsafe SMP processors: SMP with CPUs not designed for SMP."
"A module was forcibly unloaded from the system by rmmod -f."
"A hardware machine check error occurred on the system."
"A bad page was discovered on the system."
"The user has asked that the system be marked 'tainted'.
This could be because they are running software that directly
modifies the hardware, or for other reasons."
"The system has died."
"The ACPI DSDT has been overridden with one supplied by
the user instead of using the one provided by the hardware."
"A kernel warning has occurred."
"A module from drivers/staging was loaded."
"The system is working around a severe firmware bug."
"An out-of-tree module has been loaded."
)


# Kernel Taint Status Description

function TaintDescribe ()
{ arr+=("$(echo -e "\n Taint Description:")")
TD=$(cat /proc/sys/kernel/tainted)
ix=0
for _mask in 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 ; do
(($TD & $_mask)) && arr+=("$(echo -e "\n${Taint_Array[$ix]}")")
((ix++))
done
arr+=(" ")
} # End Taint Description Function


# Test for text wrapping

function wrap_rest ()
{ _str_len=0 # substr length
_sub_str=""
_line_1=1

set -- $_rest
if [ $# -eq 0 ] ; then
echo " "
return
fi

while [ $# -gt 0 ] ; do
_len=${#1}
_str_len=$((_str_len + $_len))
if [ $_str_len -lt $_wrap_col ] ; then
_sub_str="$_sub_str $1"
else
if [ $_line_1 -eq 1 ] ; then
echo "$_col_1 $_sub_str"
_line_1=0
else
echo "$_blank_col $_sub_str"
fi
_str_len=0 ; _sub_str="$1"
fi
shift
done

if [ -n "$_sub_str" ] ; then
if [ $_line_1 -eq 1 ] ; then
echo "$_col_1 $_sub_str"
else
echo "$_blank_col $_sub_str"
fi
fi

} # end function wrap_rest

#*****************************
#* main code starts here
#*****************************

# Machine Info Header

arr+=("$(echo "User Name : $(whoami)")")
arr+=("$(echo "Date : $(date +%Y-%m-%d)")")
arr+=("$(echo "Machine Info : $Version")")
arr+=("$(echo -e "\n Brought to you by the folks at alt.os.linux.ubuntu")")

# Machine Information

arr+=("$(echo -e "\n Machine Information:")")
arr+=("$(echo "Hostname : $(uname -n)")")
arr+=("$(echo "Processor : $(uname -p)")")
arr+=("$(grep -m 1 'model name' /proc/cpuinfo | tr '\t' ' ')")
arr+=("$(grep -m 1 'cpu cores' /proc/cpuinfo | tr '\t' ' ')")
set -- $(cat /proc/meminfo | tr '\t' ' ')
arr+=("$(echo "Memory : $2 kB")")
arr+=("$(echo "Video Graphics : $(lspci | sed -n 's/^.*VGA[^:]*: *//p')")")

# test for blacklisting

if [ -f /etc/modprobe.d/nvidia-installer-disable-nouveau.conf ] ; then
arr+=("Nouveau : Blacklisted")
else
arr+=("Nouveau : Not blacklisted")
fi
DirectRender=$(glxinfo 2> /dev/null | grep -m 1 direct | awk '{print $3}')
arr+=("$(echo "Direct Render : $DirectRender")")
if [ ! -d /proc/asound ] ; then
arr+=("Sound : No sound support")
else
set -- $(grep -m 1 snd /proc/asound/modules)
arr+=("$(echo "Sound : $*")")
arr+=("$(echo "SoundDriver : $(cat /proc/asound/version | tr '\t' '
')")")
fi
arr+=("$(echo "OS : $(uname -o)")")

# Distribution Information

which lsb_release > /dev/null 2>&1
if [ $? -eq 0 ] ; then
arr+=("$(echo -e "\n lsb_release Description:")")

while read -r line; do
_ix=$(expr index "$line" ':')
_wd1="${line:0:$_ix-1}"
_rest=${line:$_ix}
set -- $(IFS=':' ; echo $_rest)
arr+=("$(echo "$_wd1 : $*")")
done < <(lsb_release -a | tr -d '*\t')
fi # end if [ -e $_fn ]

# Kernel Version

arr+=("$(echo -e "\n Kernel Status:")")
arr+=("$(echo "Kernel Version : $(uname -r)")")

# Kernel Taint Status and Description

Tainted=$(cat /proc/sys/kernel/tainted)
if [ $Tainted != "0" ] ; then
arr+=("$(echo "Taint Status : Tainted ($Tainted)")")
TaintDescribe
else
arr+=("$(echo "Taint Status : Not Tainted ($Tainted)")")
fi

# User Information

arr+=("$(echo -e "\n User Information:")")
arr+=("$(echo "User Name : $(whoami)")")
arr+=("$(echo "Home Dir : $HOME")")
arr+=("$(echo "Groups : $(groups)")")

# Networking, Hostname

arr+=("$(echo -e "\n Network Information:")")
arr+=("$(echo "Hostname : $(uname -n)")")
# Nameserver

arr+=("$(echo -e "\n Nameserver Information:")")
while read -r line; do
set -- $line
if [ $# -gt 1 ] ; then
_wd1=$1
shift
arr+=("$(echo "$_wd1 : $*")")
fi
done < <(grep -v ^# /etc/resolv.conf)

#*****************************************
#* let's dump the output array and wrap
#* any lines longer than $_wrap_col
#*****************************************

for i in ${!arr[*]} ; do
line="${arr[$i]}"

_ix=$(expr index "$line" ':')
if [ $_ix -eq 0 ] ; then # no formatting required
echo "$line"
else
_c=${line:$_ix:1}
if [ "$_c" != " " ] ; then # no formatting required
echo "$line"
else
_wd1="${line:0:$_ix-2}"
_col_1="$_wd1${_blank_col:$_ix-2}"
_rest="${line:$_ix}"
_len=${#_rest}
if [ $_len -gt $_wrap_col ] ; then
wrap_rest
else
echo "$_col_1 $_rest"
fi
fi
fi
done

# Storage
echo -e "\n Storage Information:"
df -H | sort -V
echo " "

--
Marek Novotny
A member of the Linux Foundation
http://www.linuxfoundation.org
0 new messages