when I want to invoke a shell command from groovy code, like "ls" or "dir" , some people say should add "sh -c" when on linux or add "cmd -c" on Windows, so it will be "sh -c ls" or "cmd -c dir", what's the meaning of this?
cmd /c executes a command and then terminates the shell.
Type cmd /? for explanations, same for man sh.
Related
I am writing a perl script, and the objective is to kick start an xterm, follow by setenv, follow by invoke a tool that pre-installed in the system.
Here is my system call command in my perl script
system("xterm","-hold", "-e", "setenv ZI_LIBERTY_IGNORE_CONSTRUCT_FILES $RAW_RF_DIR/lib/lib2v/qcdc_ignore", "setenv HOME_0IN /p/hdk/rtl/cad/x86-64_linux26/mentor/questaCDC/V10.4g_5/linux_x86_64", "modpath -n 1 \$HOME_0IN/bin", "modpath -n 1 \$HOME_0IN/modeltech/bin", "/p/hdk/rtl/cad/x86-64_linux30/mentor/questaCDC/V10.4f_5/linux_x86_64/bin/qcdc -c -licq -do run.tcl");
xterm was able to start, however it stopped when executing the setenv, after that i tried with the new command by replacing the setenv with $ENV
system("xterm","-hold", "-e", "\$ENV{ZI_LIBERTY_IGNORE_CONSTRUCT_FILES} = \"$RAW_RF_DIR/lib/lib2v/qcdc_ignore\"", "setenv HOME_0IN /p/hdk/rtl/cad/x86-64_linux26/mentor/questaCDC/V10.4g_5/linux_x86_64", "modpath -n 1 \$HOME_0IN/bin", "modpath -n 1 \$HOME_0IN/modeltech/bin", "/p/hdk/rtl/cad/x86-64_linux30/mentor/questaCDC/V10.4f_5/linux_x86_64/bin/qcdc -c -licq -do run.tcl");
Here is the error message showing up in the new xterm (same for both approach)
Can't execvp $ENV{ZI_LIBERTY_IGNORE_CONSTRUCT_FILES} = "/nfs/fm/stod/stod4003/w.eew.100/rf_uprev_model_2020ww14p1//subIP/hip/MTLM_SA/RF.1//lib/lib2v/qcdc_ignore": No such file or directory
Please advise that how to make the series of operation works in the new xterm? Thanks!
-Eric-
The program run with -e must be a program, not a shell built-in like setenv. Off the top of my head, I can think of two solutions:
Set the environment variables before starting xterm. They would then be inherited by xterm.
Let the program run by xterm be a shell, and use that shell to set the environment variables and launch the tool. Something like this (untested):
system("xterm", "-e", "/bin/sh", "-c", "FOO=bar; FIE=fum; /run/my/program");
According to the man page I read, the following is the syntax of the -e option:
-e program [ arguments ... ]
It takes a path to a program, and optionally arguments to pass to that program. Specifically, it doesn't take a shell command. (It would be bad to accept a shell command without having the user specify for which shell!) That doesn't preclude one from running a shell command, though. This simply requires launching a shell, as the following does:
xterm -e sh -c shell_cmd
Solution:
my $script = <<'__EOS__';
export ZI_LIBERTY_IGNORE_CONSTRUCT_FILES="$RAW_RF_DIR/lib/lib2v/qcdc_ignore"
export HOME_0IN=/p/hdk/rtl/cad/x86-64_linux26/mentor/questaCDC/V10.4g_5/linux_x86_64
modpath -n 1 "$HOME_0IN/bin"
modpath -n 1 "$HOME_0IN/modeltech/bin"
/p/hdk/rtl/cad/x86-64_linux30/mentor/questaCDC/V10.4f_5/linux_x86_64/bin/qcdc -c -licq -do run.tcl
__EOS__
system("xterm", "-hold", "-e", "sh", "-c", $script)
Since a process normally passes a copy of its env vars to process it creates, you could also write the above as follows:
local $ENV{ZI_LIBERTY_IGNORE_CONSTRUCT_FILES} = "$ENV{RAW_RF_DIR}/lib/lib2v/qcdc_ignore";
local $ENV{HOME_0IN} = "/p/hdk/rtl/cad/x86-64_linux26/mentor/questaCDC/V10.4g_5/linux_x86_64";
my $script = <<'__EOS__';
modpath -n 1 "$HOME_0IN/bin"
modpath -n 1 "$HOME_0IN/modeltech/bin"
/p/hdk/rtl/cad/x86-64_linux30/mentor/questaCDC/V10.4f_5/linux_x86_64/bin/qcdc -c -licq -do run.tcl
__EOS__
system("xterm", "-hold", "-e", "sh", "-c", $script)
You can use csh similarly; I'm simply more familiar with sh.
Is there a way to pass arguments to a program being run via:
open -a /Applications/Utilities/Terminal.app ~/my_executable
I have tried:
open -a /Applications/Utilities/Terminal.app ~/my_executable arg1 arg2
But this is interpreted as telling the terminal to open ~/my_executable ~/arg1 ~/arg2.
I have tried:
open -a /Applications/Utilities/Terminal.app '~/my_executable arg1 arg2'
But it picks up arg1 and arg2 as if they were part of the path rather than arguments.
I have tried:
open -a /Applications/Utilities/Terminal.app ~/my_executable | xargs arg1 arg2
I have also tried:
open -a /Applications/Utilities/Terminal.app ~/my_executable --args arg1 arg2
But with that flag, args are passed to the terminal.
NOTE
I am only allowed to change the arguments to Terminal.app (the part within [ ]):
open -a /Applications/Utilities/Terminal.app [~/my_executable arg1 arg2]
Edit: Leaving the original answer below as some people seem to find it useful, but keep in mind that this doesn't really answers OP's question, this is to pass arguments to an app opened with "open" not to and app opened with Terminal.app which was opened with "open".
You can find your answer by running open without arguments:
% open Usage: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames] [--args arguments]
[...]
--args All remaining arguments are passed in argv to the application's main() function instead of opened.
[...]
You can see there is an option --args you can use it like this:
open ./Untitled.app --args arg1 arg2 arg3
I tested it on el Capitan (10.11.3) so I don't know if the option is present in earlier versions.
Probably the easiest way is to create a temporary shell script, e.g.
$ echo "~/my_executable arg1 arg2" > /tmp/tmp.sh ; chmod +x /tmp/tmp.sh ; open -a Terminal /tmp/tmp.sh ; rm /tmp/tmp.sh
Yes, I know. need to manage another script.
but think differently. you work not on Terminal, but on Script Editor.
(not bash scripting, but AppleScript'ing)
property testScript : "/tmp/sh.sh"
set input to display dialog "args?" default answer ""
log input
tell application "Terminal"
activate
do script testScript & " " & text returned of input
end tell
For those with having an issue with Paul R's answer, add the ; rm /tmp/tmp.sh to the tmp.sh script itself. Don't add a sleep command like Maksim as that creates a race condition.
echo "~/my_executable arg1 arg2 ; rm /tmp/tmp.sh" > /tmp/tmp.sh ; chmod +x /tmp/tmp.sh ; open -a Terminal /tmp/tmp.sh
Use the --args switch before your arguments.
open ./Terminal.app --args --your-args
From the docs:
--args: All remaining arguments are passed in argv to the application's main() function instead of opened.
I try to get the exitcode/errorlevel code from a bat file into the powershell script calling the bat file.
Althought the %ErrorLevel% is 1:
BAT file
call aCONFIGURATION
for %%f in (.\createData\*.g.sql) do sqlcmd -b -U %UserName% -P %Password% -S %sqlClonedServer% -d %sqlClonedDatabaseName% -i %%f -r1 1> NUL
echo %ERRORLEVEL%
When I do in the powershellscript
$lastexitcode its ALWAYS 0 but the %ErrorLevel% says 1
$build = "c:\my.bat"
$state = & $build
Write-Host $LASTEXITCODE
I am pulling my hairs of this crap powershell full with bugs.
I have read these links but they did not help as the result is different:
http://blogs.technet.com/b/heyscriptingguy/archive/2011/06/06/get-legacy-exit-codes-in-powershell.aspx
https://social.technet.microsoft.com/Forums/scriptcenter/en-US/05e37b8d-761b-4fd7-881e-977f114ad8d7/obtaining-errorlevel-return-codes-in-powershell-is-it-possible
How can I fix the $lastexitcode
echo %ERRORLEVEL% just writes the error code to stdout, after which the batch file exits normally.
If you want the batch script to actually return an error on exit, use exit /b [exitcode]:
call aCONFIGURATION
for %%f in (.\createData\*.g.sql) do sqlcmd -b -U %UserName% -P %Password% -S %sqlClonedServer% -d %sqlClonedDatabaseName% -i %%f -r1 1> NUL
exit /b %ERRORLEVEL%
I would like to spawn a DOS Cmd window and run hello.pl in the new cmd window.
my $cmd="cd C:/run_dir && perl hello.pl";
system("start cmd.exe /k $cmd");
The code above will correctly spawn the new dos cmd window.
However, the hello.pl program will execute from the window that the perl program was called from.
I would like "hello.pl" to run from the newly spawned cmd dos window C:/run_dir.
Thanks!
sammy
The command is
start cmd /k "cd c:\run_dir && perl hello.pl"
so you want
system('start cmd /k "cd c:\run_dir && perl hello.pl"');
I am using Psexec to run a remote batch file. I pass input to psexec and redirect it to the remote batch file which seeks a filename as its input. However while redirecting, the file name becomes a garbage as ###&#* which means actual file name is not passed to batch file which the user gives. can anyone tell what might be the reason for this.
pause
cd c:
set /P INPUT=Type input: %=%
echo Your input was: %INPUT%
copy %INPUT% \\remotemachineip\C$ && c:\psexec \\machineip cmd /k "c:\batchfile.bat arg1 < %INPUT% & del %INPUT%" -e -c -f -i
pause
pause
cd c:
set /P INPUT=Type input: %=%
echo Your input was: %INPUT%
copy %INPUT% \\remotemachineip\C$ && c:\psexec \\machineip cmd /k c:\batchfile.bat %INPUT% & del %INPUT% -c -f -i
pause
the remote batch file which seeks input from the above batch file commands on the local machine. so %1(below command) is replaced by the %INPUT%(the second argument in the cmd.exe in the above code content) which the user enters and the sqlcmd command will be executed. so the input which the user passes in the above batch file will be successfully redirected to the below batch file(content) and the command(sqlcmd below) in it will be successfully executed.
SQLCMD -Sservername -d(databasename) -iC:LINKEDSERVER.sql -v filename="%1"
for e.g if I give %INPUT% as c:\inputfile.xls it will be redirected to SQLCMD command in place of %1, so it executes it as--
SQLCMD -Sservername -d(databasename) -iC:LINKEDSERVER.sql -v filename="c:\inputfile.xls"