zsh-users
 help / color / mirror / code / Atom feed
* How should I construct this?
@ 2013-04-24 18:16 TJ Luoma
  2013-04-24 18:39 ` thomasg
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: TJ Luoma @ 2013-04-24 18:16 UTC (permalink / raw)
  To: Zsh-Users List


I am trying to write a shell script which will help my computer 
automatically join Wi-Fi networks.

Each network needs to have an SSID (which may have spaces in it) and a 
password (which may have spaces, punctuation, etc in it).

I'm trying to figure out the best way to create this.

I thought about trying to make an array or something like this where the 
first 'column' would be the SSID and the 2nd column would be the 
passwords

ALL_WIFI_NETWORKS=(
				Home					89382ashfa
				Work					0823u2j98dyumn
				"Coffee House"		""
				"Jenny's Wifi"		8675309
)


but then I need to be able to loop through $ALL_WIFI_NETWORKS using only 
first column… something like this

for SSID in {{{The First Arg in Each Line of $ALL_WIFI_NETWORKS}}}
do
		echo "foo"

done


where the part in {{{ and }}} indicates the part where I really don't 
know how to do what I want to do.

It seems like there's got to be an easier / better way of doing this, 
but I can't figure out what it is, other than keeping two lists/arrays, 
one of the SSIDs, and one with the passwords, but that seems kludgey 
because I have to ask the user (whoever uses this script besides me) to 
put the SSIDs in twice.

TjL


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:16 How should I construct this? TJ Luoma
@ 2013-04-24 18:39 ` thomasg
  2013-04-24 18:56   ` TJ Luoma
  2013-04-24 19:08   ` peter.d.miller
  2013-04-24 18:49 ` Paul Hoffman
  2013-04-24 19:50 ` Bart Schaefer
  2 siblings, 2 replies; 10+ messages in thread
From: thomasg @ 2013-04-24 18:39 UTC (permalink / raw)
  To: TJ Luoma; +Cc: Zsh-Users List

On Wed, Apr 24, 2013 at 8:16 PM, TJ Luoma <luomat@gmail.com> wrote:
>
> I am trying to write a shell script which will help my computer
> automatically join Wi-Fi networks.
>
> Each network needs to have an SSID (which may have spaces in it) and a
> password (which may have spaces, punctuation, etc in it).
>
> I'm trying to figure out the best way to create this.
>
> I thought about trying to make an array or something like this where the
> first 'column' would be the SSID and the 2nd column would be the passwords
>
> ALL_WIFI_NETWORKS=(
>                                 Home
> 89382ashfa
>                                 Work
> 0823u2j98dyumn
>                                 "Coffee House"          ""
>                                 "Jenny's Wifi"          8675309
> )
>
>
> but then I need to be able to loop through $ALL_WIFI_NETWORKS using only
> first column… something like this
>
> for SSID in {{{The First Arg in Each Line of $ALL_WIFI_NETWORKS}}}
> do
>                 echo "foo"
>
> done
>
>
> where the part in {{{ and }}} indicates the part where I really don't know
> how to do what I want to do.
>
> It seems like there's got to be an easier / better way of doing this, but I
> can't figure out what it is, other than keeping two lists/arrays, one of the
> SSIDs, and one with the passwords, but that seems kludgey because I have to
> ask the user (whoever uses this script besides me) to put the SSIDs in
> twice.
>
> TjL
>

What you want to use in a case like this are hashtables.
Basically this is a special array type, defined like this:

typeset -A ALL_WIFI_NETWORKS
ALL_WIFI_NETWORKS=(name 'password' name2 'password2)

You can then loop: for FOO in ${(k)ALL_WIFI_NETWORKS}; BAR

Hope this helps,

--
thomasg


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:16 How should I construct this? TJ Luoma
  2013-04-24 18:39 ` thomasg
@ 2013-04-24 18:49 ` Paul Hoffman
  2013-04-24 19:50 ` Bart Schaefer
  2 siblings, 0 replies; 10+ messages in thread
From: Paul Hoffman @ 2013-04-24 18:49 UTC (permalink / raw)
  To: zsh-users

On Wed, Apr 24, 2013 at 02:16:26PM -0400, TJ Luoma wrote:
> 
> I am trying to write a shell script which will help my computer
> automatically join Wi-Fi networks.
> 
> Each network needs to have an SSID (which may have spaces in it) and
> a password (which may have spaces, punctuation, etc in it).
> 
> I'm trying to figure out the best way to create this.
> 
> I thought about trying to make an array or something like this where
> the first 'column' would be the SSID and the 2nd column would be the
> passwords
> 
> ALL_WIFI_NETWORKS=(
>               Home                    89382ashfa
>               Work                    0823u2j98dyumn
>               "Coffee House"      ""
>               "Jenny's Wifi"      8675309
> )
> 
> 
> but then I need to be able to loop through $ALL_WIFI_NETWORKS using
> only first column… something like this
> 
> for SSID in {{{The First Arg in Each Line of $ALL_WIFI_NETWORKS}}}
> do
>       echo "foo"
> 
> done
> 
> 
> where the part in {{{ and }}} indicates the part where I really
> don't know how to do what I want to do.
> 
> It seems like there's got to be an easier / better way of doing
> this, but I can't figure out what it is, other than keeping two
> lists/arrays, one of the SSIDs, and one with the passwords, but that
> seems kludgey because I have to ask the user (whoever uses this
> script besides me) to put the SSIDs in twice.

Use an associative array:

    typeset -A wifi
    wifi=(
        Home            89382ashfa
        Work            0823u2j98dyumn
        'Coffee House'  ''
        "Jenny's Wiki"  8675309
    )
    for name in ${(k)wifi}; do print "$name -> ${wifi[$name]}"; done

Paul.

-- 
Paul Hoffman <nkuitse@nkuitse.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:39 ` thomasg
@ 2013-04-24 18:56   ` TJ Luoma
  2013-04-24 19:53     ` thomasg
  2013-04-24 19:08   ` peter.d.miller
  1 sibling, 1 reply; 10+ messages in thread
From: TJ Luoma @ 2013-04-24 18:56 UTC (permalink / raw)
  To: thomasg; +Cc: Zsh-Users List



On 24 Apr 2013, at 14:39, thomasg wrote:

> What you want to use in a case like this are hashtables.
> Basically this is a special array type, defined like this:

Ooh, I _knew_ there had to be a way.

Hashtables, eh? I've never used one of those before. Looking forward to 
playing with that.

(Have I mentioned that I've used zsh for ~20 years and feel like I'm 
only using 0.001% of what it can do? Stuff like this is why!)

Thanks again

TjL


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:39 ` thomasg
  2013-04-24 18:56   ` TJ Luoma
@ 2013-04-24 19:08   ` peter.d.miller
  1 sibling, 0 replies; 10+ messages in thread
From: peter.d.miller @ 2013-04-24 19:08 UTC (permalink / raw)
  To: zsh-users

On 04/24/2013 02:39 PM, thomasg wrote:
> On Wed, Apr 24, 2013 at 8:16 PM, TJ Luoma <luomat@gmail.com> wrote:
>> I am trying to write a shell script which will help my computer
>> automatically join Wi-Fi networks.
>>
>> Each network needs to have an SSID (which may have spaces in it) and a
>> password (which may have spaces, punctuation, etc in it).
>>
>> I'm trying to figure out the best way to create this.
>>
>> I thought about trying to make an array or something like this where the
>> first 'column' would be the SSID and the 2nd column would be the passwords
>>
>> ALL_WIFI_NETWORKS=(
>>                                  Home
>> 89382ashfa
>>                                  Work
>> 0823u2j98dyumn
>>                                  "Coffee House"          ""
>>                                  "Jenny's Wifi"          8675309
>> )
>>
>>
>> but then I need to be able to loop through $ALL_WIFI_NETWORKS using only
>> first column… something like this
>>
>> for SSID in {{{The First Arg in Each Line of $ALL_WIFI_NETWORKS}}}
>> do
>>                  echo "foo"
>>
>> done
>>
>>
>> where the part in {{{ and }}} indicates the part where I really don't know
>> how to do what I want to do.
>>
>> It seems like there's got to be an easier / better way of doing this, but I
>> can't figure out what it is, other than keeping two lists/arrays, one of the
>> SSIDs, and one with the passwords, but that seems kludgey because I have to
>> ask the user (whoever uses this script besides me) to put the SSIDs in
>> twice.
>>
>> TjL
>>
> What you want to use in a case like this are hashtables.
> Basically this is a special array type, defined like this:
>
> typeset -A ALL_WIFI_NETWORKS
> ALL_WIFI_NETWORKS=(name 'password' name2 'password2)
>
> You can then loop: for FOO in ${(k)ALL_WIFI_NETWORKS}; BAR
>
> Hope this helps,
>
> --
> thomasg
here's another way

I=(a b c d); for ((i=1; i<=$#I/2; i++ )); do echo $I[$((2*i-1))] 
$I[$((2*i))]; done

Peter


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:16 How should I construct this? TJ Luoma
  2013-04-24 18:39 ` thomasg
  2013-04-24 18:49 ` Paul Hoffman
@ 2013-04-24 19:50 ` Bart Schaefer
  2013-04-24 22:30   ` TJ Luoma
  2013-04-24 22:40   ` TJ Luoma
  2 siblings, 2 replies; 10+ messages in thread
From: Bart Schaefer @ 2013-04-24 19:50 UTC (permalink / raw)
  To: Zsh-Users List

On Apr 24,  2:16pm, TJ Luoma wrote:
}
} I thought about trying to make an array or something like this where the 
} first 'column' would be the SSID and the 2nd column would be the 
} passwords

In addition to Thomas's hashtables remarks, zsh "for" also supports
populating multiple variables each pass around the loop.

So if you have an ordinary array like your example (BTW I hope those
aren't your real passwords) then you can do

	for SSID WIFIPASS in $ALL_WIFI_NETWORKS
	do
		# Attempt to join network $SSID using $WIFIPASS
	done

If you declare ALL_WIFI_NETWORKS as a hash table as Thomas suggested, then
you can still do

	for SSID WIFIPASS in ${(kv)ALL_WIFI_NETWORKS}
	do
		# ...
	done

but the SSID probably won't be in the same order as you assigned them,
because hashes return their values in hash bucket order.  If you need
to preserve a fixed ordering, you have to use a real array.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 18:56   ` TJ Luoma
@ 2013-04-24 19:53     ` thomasg
  0 siblings, 0 replies; 10+ messages in thread
From: thomasg @ 2013-04-24 19:53 UTC (permalink / raw)
  To: TJ Luoma; +Cc: Zsh-Users List

On Wed, Apr 24, 2013 at 8:56 PM, TJ Luoma <tj@luo.ma> wrote:
>
>
> On 24 Apr 2013, at 14:39, thomasg wrote:
>
>> What you want to use in a case like this are hashtables.
>> Basically this is a special array type, defined like this:
>
>
> Ooh, I _knew_ there had to be a way.
>
> Hashtables, eh? I've never used one of those before. Looking forward to
> playing with that.

Zsh calls this Associative Array btw., hashtable isn't technically
correct I guess (even though it looks like one :)

> (Have I mentioned that I've used zsh for ~20 years and feel like I'm only
> using 0.001% of what it can do? Stuff like this is why!)

Sometimes I think even the maintainers of zsh have to feel this way :)

> Thanks again
>
> TjL
>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 19:50 ` Bart Schaefer
@ 2013-04-24 22:30   ` TJ Luoma
  2013-04-24 22:40   ` TJ Luoma
  1 sibling, 0 replies; 10+ messages in thread
From: TJ Luoma @ 2013-04-24 22:30 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh-Users List



On 24 Apr 2013, at 15:50, Bart Schaefer wrote:

> In addition to Thomas's hashtables remarks, zsh "for" also supports
> populating multiple variables each pass around the loop.
>
> So if you have an ordinary array like your example (BTW I hope those
> aren't your real passwords) then you can do

Ha… no, just randomly pressed keys… (well, except for Jenny's which 
is an homage to Tommy Tutone :)



> but the SSID probably won't be in the same order as you assigned them,
> because hashes return their values in hash bucket order.  If you need
> to preserve a fixed ordering, you have to use a real array.

Ooh, yeah, that's important, as the array lists SSIDs in preferred 
order.

Thanks!

TjL


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 19:50 ` Bart Schaefer
  2013-04-24 22:30   ` TJ Luoma
@ 2013-04-24 22:40   ` TJ Luoma
  2013-04-25  1:29     ` Paul Hoffman
  1 sibling, 1 reply; 10+ messages in thread
From: TJ Luoma @ 2013-04-24 22:40 UTC (permalink / raw)
  To: Zsh-Users List



On 24 Apr 2013, at 15:50, Bart Schaefer wrote:

> In addition to Thomas's hashtables remarks, zsh "for" also supports
> populating multiple variables each pass around the loop.
>
> So if you have an ordinary array like your example (BTW I hope those
> aren't your real passwords) then you can do
>
> 	for SSID WIFIPASS in $ALL_WIFI_NETWORKS
> 	do
> 		# Attempt to join network $SSID using $WIFIPASS
> 	done

The only drawback that I have found to this is that it ignores "" for 
empty passwords

# INPUT

	ALL_WIFI_NETWORKS=(
		"Home"				"89382ashfa"
		"Work"				"0823u2j98dyumn"
		"Coffee House"		""
		"Jenny's Wifi"		"8675309"
	)

	for SSID WIFIPASS in $ALL_WIFI_NETWORKS
	do
			echo "SSID: ${SSID}\tPass: ${WIFIPASS}\n"
	done

# RESULTS

	SSID: Home	Pass: 89382ashfa

	SSID: Work	Pass: 0823u2j98dyumn

	SSID: Coffee House	Pass: Jenny's Wifi

	SSID: 8675309	Pass:



So I'll just use a single character to represent empty passwords, such 
as


	ALL_WIFI_NETWORKS=(
		"Home"				"89382ashfa"
		"Work"				"0823u2j98dyumn"
		"Coffee House"		"-"
		"Jenny's Wifi"		"8675309"
	)

	for SSID WIFIPASS in $ALL_WIFI_NETWORKS
	do
			echo "SSID: ${SSID}\tPass: ${WIFIPASS}\n"
	done

and then check for a password equal to - before sending the command.

TjL


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How should I construct this?
  2013-04-24 22:40   ` TJ Luoma
@ 2013-04-25  1:29     ` Paul Hoffman
  0 siblings, 0 replies; 10+ messages in thread
From: Paul Hoffman @ 2013-04-25  1:29 UTC (permalink / raw)
  To: zsh-users

On Wed, Apr 24, 2013 at 06:40:25PM -0400, TJ Luoma wrote:
> 
> 
> On 24 Apr 2013, at 15:50, Bart Schaefer wrote:
> 
> >In addition to Thomas's hashtables remarks, zsh "for" also supports
> >populating multiple variables each pass around the loop.
> >
> >So if you have an ordinary array like your example (BTW I hope those
> >aren't your real passwords) then you can do
> >
> >	for SSID WIFIPASS in $ALL_WIFI_NETWORKS
> >	do
> >		# Attempt to join network $SSID using $WIFIPASS
> >	done
> 
> The only drawback that I have found to this is that it ignores "" for
> empty passwords

The "@" flag is your friend (see "Parameter Expansion Flags" in 
zshexpn):

    typeset -a wifi
    wifi=( ... )
    for ssid pass in "${(@)wifi}"; do ...; done

Sorry for the all-lower-case examples -- I'm lazy.

Paul.

-- 
Paul Hoffman <nkuitse@nkuitse.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-04-25  1:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-24 18:16 How should I construct this? TJ Luoma
2013-04-24 18:39 ` thomasg
2013-04-24 18:56   ` TJ Luoma
2013-04-24 19:53     ` thomasg
2013-04-24 19:08   ` peter.d.miller
2013-04-24 18:49 ` Paul Hoffman
2013-04-24 19:50 ` Bart Schaefer
2013-04-24 22:30   ` TJ Luoma
2013-04-24 22:40   ` TJ Luoma
2013-04-25  1:29     ` Paul Hoffman

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).