My DockerFile has an ENTRYPOINT that just echoes ENTRYPOINT echo %windir%\system32\inetsrv\appcmd to the command window.
This syntax works: ENTRYPOINT echo %windir%\system32\inetsrv\appcmd
This doesn't: ENTRYPOINT ["echo", "%windir%\system32\inetsrv\appcmd"]
The output is '[\"echo\"' is not recognized as an internal or external command, operable program or batch file.
What's the different between these two syntaxes?
The answer was in the documentation (who'd have thought that?)
The first form executes in a shell, and is therefore equivalent to anything you might type into it.
The second form doesn't execute in a shell, it just executes the file with the provided arguments.
Related
TL;DR; I guess the shell that std::system use, is sh. But, I'm not sure.
I tried to print the shell, using this code: std::system("echo $SHELL"), and the output was /bin/bash. It was weird for me. So, I wanted to see, what happens if I do that in sh? And, the same output: /bin/bash. Also, if I use a command like SHELL="/usr/bin/something", to set the SHELL variable to another string, it will print the new string that I set to it (/usr/bin/something), and it looks it's not a good way to see what shell it's using. Then, I tried to check it, using the ps command, and the output was: bash, a.out, ps. It was weird to see bash in this list. So, I created a custom shell, and change the shell in gnome-terminal to it:
#include <iostream>
int main()
{
std::string input;
while (true)
{
std::string command;
std::getline(std::cin, command);
std::system(command.c_str());
}
}
Now, it's easier to test, and I think, the results is better.
Then, I tried to test the ps command again, but in the custom shell, and the results was: test_shell, ps.
It was weird again. How the shell isn't sh, nor bash? And, the final test I did was: echo $0. And, the results was sh, in both custom shell, and normal program.
Edit
It seems like /bin/sh is linked to /bin/bash (ll /bin/sh command's output is /bin/sh -> bash), and actually, it seems like the only difference between sh and bash is filename, and the files's contents are the same. I checked the difference between these files with diff command too:
$ xxd /bin/sh > sh
$ xxd /bin/bash > bash
$ diff sh bash
(+ Yes, $SHELL doesn't means the running shell (I didn't know that when I was testing, and I just wanted to see what happens))
The GNU sources (https://github.com/lattera/glibc/blob/master/sysdeps/posix/system.c) say
/bin/sh
So, whatever /bin/sh is hardlinked to is the shell invoked by std::system() on Linux.
(This is correct, as /bin/sh is expected to be linked to a sane shell capable of doing things with the system.)
According to cppreference.com, std::system
calls the host environment's command processor (e.g. /bin/sh, cmd.exe, command.com)
This means the shell used will depend on the operating system.
On any POSIX OS (including Linux), the shell used by std::system is /bin/sh. (Though as the OP points out, /bin/sh could be a symlink to another shell.)
As for the SHELL environment variable, as has been pointed out in the comments, this environment variable cannot be used to reliably identify the running shell program. SHELL is defined by POSIX to
represent a pathname of the user's preferred command language interpreter
(source)
I am trying to launch a legacy application in GDB, and it requires that it's argv[0] value not contain anything other than alphanumeric characters.
Whenever I launch the program in GDB it seems that it expands the name to be the full path before running the program, so I get an error like (because it can't deal with the slashes):
"Cannot find /home/user/myapp ..."
Is it possible to run a program in GDB with a relative path, so that it will just see "myapp"?
Gdb normally runs target commands using the shell command line
exec program_pathname program_arguments
But it has a set exec-wrapper command that will change this to
exec exec_wrapper program_pathname program_arguments
The exec_wrapper is often another command, but it can be an option that the exec command accepts.
Many shells (bash, zsh, ksh93) support a -a option to the exec command to set argv[0].
So, if your shell supports exec -a, you can do the following to invoke /home/user/myapp with argv[0]==myapp:
(gdb) set exec-wrapper -a myapp
So basiclly im trying to use this:
int main()
{
system("adb kill-server \n"
"adb devices \n"
"adb start-server & \n"
"var=$(adb shell \"pidof com.rok\")\n"
"AFTER=`echo $var | sed 's/\\r//g'`\n"
"echo \"$AFTER\"\n"
"adb shell \"kill -STOP $AFTER\"\n"
"adb shell sleep 2\n"
"adb shell \"kill -CONT $AFTER\"");
return 0;
}
thing is this works in Clion without any error, but i must do this in visual studio and in visual studio i cannot do it like that i have to do every system command alone like:
system("adb kill-server");
system("adb devices");
system("adb start-server");
system("var=$(adb shell \"pidof com.rok\")");
system("AFTER=`echo $var | sed 's/\\r//g'`");
system("adb shell \"kill -STOP $AFTER\"");
so now the thing is when i run it like this everything works except this two lines:
system("var=$(adb shell \"pidof com.rok\")");
system("AFTER=`echo $var | sed 's/\\r//g'`");
even though they perfectly works on clion they dont in visual studio, i cannot find a way to solve this problem, this is the error:
'var' is not recognized as an internal or external command,
operable program or batch file.
'AFTER' is not recognized as an internal or external command,
operable program or batch file.
can anyone explain why this happens? and how can i solve this problem?
Each call of system() creates it's own shell as a subprocess, that's why multiple subsequent system() calls don't work if you e.g. try to set shell variables or do a cd command (expecting subsequent commands running in a specific directory).
The easiest way to do it, is to create a little temporary script file containing all the commands and execute this one with a single system() call:
// A raw string literal to make escaping easier
// (see https://en.cppreference.com/w/cpp/language/string_literal)
std::string cmds = R"xxx(
adb kill-server
adb devices
adb start-server &
var=$(adb shell "pidof com.rok")
AFTER=`echo $var | sed 's/\r//g'`
echo "$AFTER"
adb shell "kill -STOP $AFTER"
adb shell sleep 2
adb shell "kill -CONT $AFTER"
)xxx";
std::ofstream cmdFile("tempCmdFile.cmd");
cmdFile << cmds;
cmdFile.close();
system("tempCmdFile.cmd");
You probably should tidy up the tempCmdFile.cmd up afterwards (i.e. remove it). But I hope you grasp what the code above does.
Also I am not so sure that
AFTER=`echo $var | sed 's/\r//g'`
will work in a windows shell, as you expect it to do. You probably need a different solution for that, or a *nix like shell to run it (e.g. MinGw provides one).
I have built a bash script to start up some processes in my system. It simply calls the process and associated config file. Same as I would call from the command line.
#!/bin/bash
# Start specified process in a new session
setsid $1 &>/dev/null &
So to start up someprocess, I would call from the command line:
root#supercomputer:~# start someprocess
This works like a charm. Every process, every time. But when I make a system call from a different running C++ process, someprocess never starts up.
system( "start someprocess" )
This approach for 90% of my processes, except for one. The only difference in the working and not working processes is that the non-working one uses proprietary libraries underneath. I recently added the setsid option to the bash script in hopes that starting a new session would help, but it made no difference. I've also tried popen, and execv. No change.
So my question is what is the difference between calling something with system() and just making that same call from the command line?
All processes are written in C++ on Linux.
.bashrc is only invoked if bash is run as interactive, non-login shell. If it's invoked as non-interactive shell, as when using system() on a script with a bash shebang, it only reads the configuration file pointed to by $BASH_ENV.
That means you have the following options:
add -l to the shebang - causes the shell to read ~/.profile at startup
set $BASH_ENV to the script you want sourced before calling system()
add -i to the shebang - invokes bash as interactive shell and causes it to read ~/.bashrc, but will also effect how bash handles input/output.
I'd recommend the first option.
You can find a detailed explanation of how bash reads it's startup files here. I'm not sure this will solve your problem completely, but it may at leas shed some light on that part of the issue.
Check the environment variables that are used in the system() call. For example, call system to print out some of the variables, and see if they match what you see from the command line.
Likely they are not being sourced correctly.
I have a question regarding executing shell commands in c++. I'm building an application in winforms, vs 2008. My application has a button, when clicked should decode a binary file to a .csv file. I can decode files by first going to the right directory (cd Test_Copy2) and then execute a command in the command prompt (java -jar tool.jar -b x.fit x.csv). I tried a lot of different stuff but unfortunately got none to work!
I tried using:
system, _popen, ShellExecute(NULL, L"open", L"C:\\WINDOWS\\system32\\cmd.exe ", L"java -jar Tool.jar -b x.fit x.csv", L"C:\\Test_Copy2", SW_SHOWNORMAL)
Can anyone please provide me with an example on how to do that? I dont know where I'm going wrong, most of the time the command prompt opens but no command is executed!
If you really want to run the jar in a cmd.exe instance, you need to add one of the correct command line switches to cmd.exe for it to work the way you want it to:
/C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
For instance, your command string should be:
C:\\WINDOWS\\system32\\cmd.exe /c java -jar Tool.jar -b x.fit x.csv
You can use the system() function to execute shell commands.
For example:
system("DIR") executes the DIR command in the CMD shell. The default directory at the start is the directory you're .exe file is located.
'system("PAUSE")` executes the PAUSE command.
The command/s you wannt to execute should be passed as a constant string to the function.
Edit:
For you paritcular program the syntax (IMO) would be:
system("java -jar Tool.jar -b x.fit x.csv")