Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: newbie, scripting problems..



On Dec 23,  1:43pm, Per Blomqvist wrote:
} 
} Im newbie in shell (zsh).

Welcome.

} I rewriting a bash-script, to function also in this "Zsh". And running
} into a several problems...:

Unless your goal is to learn how to write the script in "native" zsh,
you may want to start by placing
	emulate sh
somewhere near the top.  This will reduce the number of changes that
you need to make.  You say later that you want the script to run in
bash as well, so something like

	[[ -n $ZSH_VERSION ]] && emulate sh

However, I'll answer here a question that's going to come up later:
Arrays are an extension to standard POSIX shell syntax, so there is no
requirement that they be implemented in compatible ways in different
shells.  It's possible to write a script that will run in both bash and
zsh, but it's not possible in any straightforward way to write a script
using array syntax that will run unmodified in both bash and zsh.

} 1. Cant make a dynamic loaded array. In bash:
} ToBe[${#ToBe[@]}]="$BTheFile" (that I do inside a loop, with some condition)

Depending on how ToBe received its initial value, the problem is likely
twofold:  (1) In zsh, variables are scalars unless either assigned with
the var=( words... ) syntax or declared in advance with "typeset -a var"
(sometimes written as the synonymous "declare -a var").  (2) Scalars in
zsh can be subscripted to extract or modify substrings.

So first try adding
	[[ -n $ZSH_VERSION ]] && declare -a ToBe
somewhere before its first use (outside the loop).  That should fix the 
assignment you show above.

Then you may want to try changing the assignment to

    ToBe+=( "$BTheFile" )

which is a somewhat more efficient way to append to an array in recent
versions of zsh.  You didn't say which version you have, so it may not
work for you.

} 2. Wildchars, or if its spelled wildcharts. Test of these. Wild
} something I saw in some docs, was this zsh fancy thing. In Bash, this
} works: "[[ $A = $B ]] && then do something" (there $A maybe a file , and
} $B a wildstring as "*.avi")

It's "wildchars" or "glob patterns" or often just "patterns".

This is one of those things that would be fixed by "emulate sh".  The
real zsh way is

	[[ $A = $~B ]]
 
In "native" zsh, variable expansions are implicitly quoted, and need to
be un-quoted in various specific ways in to behave like traditional
/bin/sh variables.  Another case is $=B which is needed to split the
value into words on whitespace.

} 3. "read" didnt read space-separated lines as arrays, by default. But
} did with option "-A". BUT this caused error if I later runned the script
} as Bash. (I want it to be both bash and zsh compatible)

See the remark above about array incompatibility.  However, I think the
real problem here is not with reading into the variable, but with
splitting the value on spaces when you refer to it.  Bash "read" does
not input space-separated lines as arrays, either.  This is another
case that I suspect will be fixed by "emulate sh", but in native zsh
you probably want to use the $=B form when referring to the variable
into which your space-separated line was read.

} Some more fuzz, I made some clouds in awk
} #aaa=$( echo "one two three" | awk '{ ORS=" "; print "(";  i=1; while (i
} <= NF) { print "\""$i"\"" ; i++ } print ")\n" }' )
} # Then the new ("one" "two" "tree") is still only one single string.

Two things are going on here:  (1) Like variable references, variable
assignments are not split on whitespace by default in zsh unless they
are array assignments of the aaa=( words... ) form.  (2) Parens as a
syntax element are parsed BEFORE substitutions are done, so the fact
that your awk statement printed a leading and trailing paren has no
syntactic significance to the shell parser.  They're just ordinary
characters and become part of the string assigned to $aaa.

Problem (1) is, again, fixed by "emulate sh".  For problem (2) you'll
have to remove the parens from what awk prints.

} # THIS WORKS:
} # aaa=( $( echo "one two three" | awk '{ ORS=" "; i=1; while (i <= NF) {
} print "\""$i"\"" ; i++ } }' ) )

That would be the traditional zsh way of doing it.

} One more question, how does "fish" compare to "zsh"?

I'm not very familiar with "fish" but on a quick once-over:

(1) Fish makes no attempt to conform to traditional POSIX syntax.  It
    has syntax that looks more like python or csh.  This theoretically
    makes it easy to learn, but there's never going to be such a thing
    as a professional fish programmer - it's strictly a shell for
    casual users and hobbyists.
(2) The fish editor and completion system are (in operation, not in
    completion programming) much like zsh's.  I won't go so far as to
    suggest "modeled on" but I wouldn't be surprised.
(3) The main feature fish has that zsh doesn't is interactive syntax
    highlighting in multiple colors.



Messages sorted by: Reverse Date, Date, Thread, Author