Passing param to function in ksh script - unix

The parameter passed is changed when printed from inside the function
print "param: $FILEPREFIX" 1>&2; #return finyear*
func_copy $FILEPREFIX
then in function
function func_copy
{
fp=$1
print "param: $fp" 1>&2; #returns finyear.scr which is a script file name
what would i be doing wrong here

When you invoke func_copy $FILEPREFIX and FILEPREFIX contains finyear*, the shell expands the variable and then does wild-card matching, so the name finyear* is changed to finyear.scr in your directory. To avoid the expansion, enclose the name in double quotes:
func_copy "$FILEPREFIX"
(Using double quotes around a variable expansion is usually, but not always, a good idea.)
See the Bash manual on shell expansions for the sequence of operations in Bash. The POSIX shell (sh) has similar rules, and Korn shell will likewise be similar — they all have a common ancestor, the Bourne shell.

Related

zsh using a variable in a command within a function

In .zsh, in my .zshrc file I'd like to set up a function to cd to a directory I input, but using an existing variable to write the common ~/path/to/parent/directory/$input
I've been unable to find out what the correct syntax is for this particular usage. For example, I want to enter
goto mydir
and execute a cd to ~/path/to/parent/directory/mydir
But I get an error: gt:cd:3 no such file or directory ~/path/to/parent/directory/mydir even though that directory exists.
This is the variable declaration and function I am trying:
export SITESPATH="~/path/to/parent/directory"
function gt(){
echo "your site name is $#"
echo "SITESPATH: " $SITESPATH "\n"
cd $SITESPATH/$#
}
It makes no difference if I use the above, without quotes, or "cd $SITESPATH/$#" with quotes.
I don't see the point in using $# in your function, since you expect only one argument. $1 would be sufficient.
The problem is in the tilde which is contained in your variable SITEPATH. You need to have it expanded. You can either do it by writing
export SITESPATH=~/path/to/parent/directory
when you define the variable, or inside your function by doing a
cd ${~SITESPATH)/$1
A third possibility is to turn on glob_subst in your shell:
setopt glob_subst
In this case, you can keep your current definition of $SITESPATH, and tilde-substitution will happen automatically.

noglob function then use ls with param?

I just want to pass a glob through and then use it against ls directly. The simplest example would be:
test() { ls -d ~/$1 }
alias test="noglob test"
test D*
If I simply run ls D in my home directory: it outputs three files. but if I run the snippet provided, I get "/Users/jubi/D*": No such file or directory. What should I be doing? thanks!
The authoritative and complete documentation of Zsh expansion mechanism is located at http://zsh.sourceforge.net/Doc/Release/Expansion.html.
Here's the reason your version doesn't work:
If a word contains an unquoted instance of one of the characters ‘*’, ‘(’, ‘|’, ‘<’, ‘[’, or ‘?’, it is regarded as a pattern for filename generation, unless the GLOB option is unset.
emphasis mine. Your glob operator, generated by parameter expansion, isn't considered unquoted.
You need the GLOB_SUBST option to evaluate the parameter expansion result as a glob pattern. a setopt globsubst, unsetopt globsubst pair works, of course, but the easiest way is to use the following pattern specifically for this purpose:
${~spec}
Turn on the GLOB_SUBST option for the evaluation of spec; if the ‘~’ is doubled, turn it off. When this option is set, the string resulting from the expansion will be interpreted as a pattern anywhere that is possible, such as in filename expansion and filename generation and pattern-matching contexts like the right hand side of the ‘=’ and ‘!=’ operators in conditions.
In nested substitutions, note that the effect of the ~ applies to the result of the current level of substitution. A surrounding pattern operation on the result may cancel it. Hence, for example, if the parameter foo is set to *, ${~foo//\*/*.c} is substituted by the pattern *.c, which may be expanded by filename generation, but ${${~foo}//\*/*.c} substitutes to the string *.c, which will not be further expanded.
So:
t () { ls -d ~/${~1} }
alias t="noglob t"
By the way, test is a POSIX shell builtin (aka [). Don't shadow it.

zsh: unknown file attribute

I have the following function in my .zshrc which, in theory, allows me to write a commit message without needing quotation marks.
cm(){
git commit -m "$#"
}
When I run it (cm foo bar), I get the following error:
zsh: unknown file attribute
Does $# mean the same thing in zsh as it does in bash?
Accoring to this article, * and # both contain an array of the positional parameters.
The parameters *, # and argv are arrays containing all the positional parameters; thus $argv[n], etc., is equivalent to simply $n.
And...
A subscript of the form [*] or [#] evaluates to all elements of an array; there is no difference between the two except when they appear within double quotes. "$foo[*]" evaluates to "$foo[1] $foo[2] ...", whereas "$foo[#]" evaluates to "$foo[1]" "$foo[2]" ....

Checking for environment variable

Using this UNIX script I am able to check if variable TEST_VAR is set or not:
: ${TEST_VAR:?"Not set or empty."}
I am new to unix so can someone please explain what is this command.
From bash manual:
${parameter:?word}
If parameter is null or unset, the expansion of word (or a message to
that effect if word is not present) is written to the standard error
and the shell, if it is not interactive, exits. Otherwise, the value
of parameter is substituted.
It is the original shell comment notation (before '#' to end of line). For a long time, Bourne shell scripts had a colon as the first character. The C Shell would read a script and use the first character to determine whether it was for the C Shell (a '#' hash) or the Bourne shell (a ':' colon). Then the kernel got in on the act and added support for '#!/path/to/program' and the Bourne shell got '#' comments, and the colon convention went by the wayside
Have a look at this similar question:
What's a concise way to check that environment variables are set in a Unix shell script?

how does unix handle full path name with space and arguments?

How does unix handle full path name with space and arguments ?
In windows we quote the path and add the command-line arguments after, how is it in unix?
"c:\foo folder with space\foo.exe" -help
update:
I meant how do I recognize a path from the command line arguments.
You can either quote it like your Windows example above, or escape the spaces with backslashes:
"/foo folder with space/foo" --help
/foo\ folder\ with\ space/foo --help
You can quote if you like, or you can escape the spaces with a preceding \, but most UNIX paths (Mac OS X aside) don't have spaces in them.
/Applications/Image\ Capture.app/Contents/MacOS/Image\ Capture
"/Applications/Image Capture.app/Contents/MacOS/Image Capture"
/Applications/"Image Capture.app"/Contents/MacOS/"Image Capture"
All refer to the same executable under Mac OS X.
I'm not sure what you mean about recognizing a path - if any of the above paths are passed as a parameter to a program the shell will put the entire string in one variable - you don't have to parse multiple arguments to get the entire path.
Since spaces are used to separate command line arguments, they have to be escaped from the shell. This can be done with either a backslash () or quotes:
"/path/with/spaces in it/to/a/file"
somecommand -spaced\ option
somecommand "-spaced option"
somecommand '-spaced option'
This is assuming you're running from a shell. If you're writing code, you can usually pass the arguments directly, avoiding the problem:
Example in perl. Instead of doing:
print("code sample");system("somecommand -spaced option");
you can do
print("code sample");system("somecommand", "-spaced option");
Since when you pass the system() call a list, it doesn't break arguments on spaces like it does with a single argument call.
Also be careful with double-quotes -- on the Unix shell this expands variables. Some are obvious (like $foo and \t) but some are not (like !foo).
For safety, use single-quotes!
You can quote the entire path as in windows or you can escape the spaces like in:
/foo\ folder\ with\ space/foo.sh -help
Both ways will work!
I would also like to point out that in case you are using command line arguments as part of a shell script (.sh file), then within the script, you would need to enclose the argument in quotes. So if your command looks like
>scriptName.sh arg1 arg2
And arg1 is your path that has spaces, then within the shell script, you would need to refer to it as "$arg1" instead of $arg1
Here are the details
If the normal ways don't work, trying substituting spaces with %20.
This worked for me when dealing with SSH and other domain-style commands like auto_smb.

Resources