What is the Powershell analogue of $# used to call another command? - scripting

In a Unix shell script, to call command foo on the original arguments to the script, you just write
foo $#
In Powershell, $args is an array of (typically) strings holding the current script's arguments. If you write
foo $args
will the same thing happen as in bash or other typical Unix shell script interpreters?

You want to use argument splatting which is new in PowerShell 2.0. The variable used for splatting can be either an array (args are bound positionally) or a hashtable (keys map to parameter names and their values provide the argument). If you don't declare any parameters then use #args. The problem with attempting to use $args is that it will be sent as an array to the first parmeter rather than splatted across all the parametets. However many folks do declare parameter. In this case you want to use #PSBoundParameters e.g.:
foo #PSBoundParameters

Related

How to use KSH variable in string and Robotframework not to interpret it for a case variable

I tried to use Robot to do the following operation in KSH to remove the ".auto" postfix in a directory:
Write for file in .auto; do mv $file ${file%.}; done
The ${file%.} is for KSH variable however Robot always considered it as Robot variable and gave the error message: "Resolving variable '${file%.}' failed: Variable '${file}' not found."
Is there any way to tell Robot that the ${file%.*} is not for a Robot variable?
If a string has something the framework may interpret as inline variable usage - escape it, with the \ char.
In your case, put it in front of the ${:
Write for file in .auto; do mv $file \${file%.}; done

Difference between using "set" and not using set for variables? In Cygwin.

I don’t understand the difference between:
set youtube=’https://youtube.com’
and
youtube=’https://youtube.com’
With the second one, I’m able to use it in the middle of a command, such as:
cygstart $youtube
and that works.
Why and how are these different? They both set variables?
And, when I don't use the word "set" I have to expand the variable using $?
Thanks.
The two commands are completely unrelated; set youtube='https://youtube.com' has nothing to do with $youtube. What it does is, it sets $1 to the whole string 'youtube=https://youtube.com'.
Per http://www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin, set is a shell builtin with three distinct purposes:
If you don't give it any options or arguments, it prints out all the existing shell variables and functions.
It has various options that let you change various properties of the shell. For example, set -C tells the shell that you don't want > to overwrite existing files (and that you instead want commands to fail if they would otherwise do that); and set +C tells the shell that never mind, you now want > to be able to overwrite files again.
Any arguments, other than options, replace the positional parameters ($1 and $2 and so on, as well as $# and $*).
Since set youtube='https://youtube.com' calls set with exactly one argument, namely youtube=https://youtube.com, it has the effect of setting the first positional parameter ($1) to youtube=https://youtube.com.
Note that youtube='https://youtube.com' is a somewhat misleading way to write youtube=https://youtube.com; the single-quotes aren't doing anything here (since the sole purpose of single-quotes is to escape whitespace and special characters, and https://youtube.com doesn't have any of these).

Is it possible to pass the value of a parameter to an UDF constructor?

I've written a UDF which takes a constructor parameter.
I've successfully initialized and used it in grunt as
grunt> register mylib.jar
grunt> define Function com.company.pig.udf.MyFunction('param-value');
But I can't initialize it using a Pig parameter as in
grunt> define Decrypt com.company.pig.udf.MyFunction($secret);
or
grunt> define Decrypt com.company.pig.udf.MyFunction('$secret');
I tried to initialize $secret using both -param and -param_file options.
Are Pig parameters supported as UDF constructor arguments at all?
The function I'm loading is used to decrypt some data and the param-value contains special characters as "%$!" but no quotes. So I'm unsure whether I'm running into an value expansion issue or a parameter there is just not being expanded.
I'm setting the parameter value without quotes in a param file:
secret = My$ecr%t!
It is definitely possible to pass parameter values to UDFs. The problem seems to be the $ sign.
This should the correct syntax:
define Decrypt com.company.pig.udf.MyFunction('$secret');
In your parameter file put:
secret=My\$ecr%t!
The -dryrun option can be helpful for this it will create a file called <nameofpigfile>.pig.subsituted and not run the actual script.
pig -x local -dryrun -f mypigfile.pig -param_file myparameterfile
Also, you probably need pig >= 0.11
https://issues.apache.org/jira/browse/PIG-2931

How to add a variable amount of arguments to exec in tcl?

I've been working with TCL for some time now, and I have spent a long time trying to do the following (it seems easy and I think it should be, but I can't get it right):
I need to execute an external program by means of a tcl script. For that, I use the exec command. For using this external program, I need to input a variable amount of files. If I called this program straight from a cmd window, it would be something like:
C:\>myprogram -i file1 -i file2 -i file3 (etc., etc.)
However, when trying to implement this in a dynamic/variable way through tcl I get into trouble. The way I do it is by storing in some variable myvar all the "-i filex" I need (done in a loop), and then pass that as a parameter to the exec command. It would look something like:
exec myprogram $myvar
Doing that apparently creates some issues, because this myprogram fails to "see" myvar. I'm guessing that there is some sort of hidden terminator or some clash of different types of arguments that makes that in the end the exec command "sees" only myprogram.
So, my question is, does anyone know how to insert variable arguments into a call to exec?
You can use {*} or eval. See this question for example.
Specializing for your case:
Tcl 8.5 (and later):
exec myprogram {*}$myvar
Tcl 8.4 (and before):
eval [list exec myprogram] [lrange $myvar 0 end]
# Or...
eval [linsert $myvar 0 exec myprogram]
That's right, the old version is ugly (or non-obvious, or both). Because of that, people tended to write this instead:
eval exec myprogram $myvar
but that was slower than expected (OK, not so relevant when running an external program!) and has hazards when $myvar isn't a canonically-formatted list due to the way that eval works. It used to catch out even experienced Tcl programmers, and that's why we introduced new syntax in 8.5, which is specified to be surprise-free and is pretty short too.

Using variables in a vim shell command

How would I go about using a variable in a vim shell command (one done with !) in a vimscript? For instance, something kind of like this: (just an example, not what I'm really trying to do)
function Ls(dir)
!ls a:dir
endfunction
Use the execute command. Everything after it is an expression that evaluates to a string, which it then executes like a command you had typed in yourself.
function Ls(dir)
execute '!ls ' . a:dir
endfunction
This says, "Evaluate the expression '!ls ' . a:dir and then execute it." The variable a:dir is expanded, the dot concatenates the two strings into '!ls whatever' and then that is executed as if you had typed it.