I am using the ftm cli by Oracle. When I run a command, it asks for a password by saying "Enter a password". I am writing a script which uses this command and so I want to enter the password programatically.
Here's what I have tried -
echo "password" | java -jar ftmcli.jar list
But this doesn't work. Any idea what to do to make it work?
Without being able to look into the source code of ftmcli, I presume that Oracle is using Console.readPassword() from the java.io.Console class. However, there is a snag with this function:
public final class Console
Methods to access the character-based console device, if any,
associated with the current Java virtual machine.
Whether a virtual machine has a console is dependent upon the
underlying platform and also upon the manner in which the virtual
machine is invoked. If the virtual machine is started from an
interactive command line without redirecting the standard input and
output streams then its console will exist and will typically be
connected to the keyboard and display from which the virtual machine
was launched. If the virtual machine is started automatically, for
example by a background job scheduler, then it will typically not have
a console.
If this virtual machine has a console then it is represented by a
unique instance of this class which can be obtained by invoking the
System.console() method. If no console device is available then an
invocation of that method will return null.
By piping/redirecting the stdout of echo to the JVM, the Java method System.console() will return null and hence not read anything from your redirection.
Look at the following questions which handle the same problem, but on Java side: "How to handle java passwd reading when System.console() returns null?" or How to pipe input to Java program with bash
On your side, there is more or less nothing you can really do. Executing echo $password | java -jar ftmcli.jar list or java -jar ftmcli.jar list <<< $password will always fail as long Oracle doesn't change the way how ftmcli reads the password from stdin.
If you are ready for a one time password setup, then follow the below steps.
run java -jar ftmcli.jar --save-auth-key
You will be prompted for teh password and once it is given, the file will be uploaded and a ftmclikeystore file is created under ftmcli folder.
Now as long as if you don't change the user, then ftmcli will take the password from this file.
Found this little but fantastic tool called expect does the magic:
$ ./expect.script
spawn java -cp /tmp/brm-test/oraclepki.jar:/tmp/brm-test/BRMActions.jar com.oracle.installer.brm.BRMInstallHelper 7 /tmp/brm-test/client upgC
Enter Password for the wallet:
$
Perhaps it's not very much visible in the snippet above, but it is working:
$ cat /tmp/brm-test/client/.wp
upgC=MyMag1cPa$$word#
What is in the expect.script?
$ cat expect.script
#!/usr/bin/expect
stty -echo
spawn java -cp /tmp/brm-test/oraclepki.jar:/tmp/brm-test/BRMActions.jar com.oracle.installer.brm.BRMInstallHelper 7 /tmp/brm-test/client upgC
expect "Enter Password for the wallet:"
send "MyMag1cPa$$word#\r"
interact
Seems this can be used also in Chef, see this cookbook.
I hope it will help,
Jarek
I am running ubuntu 13.10 and want to write a bash script that will execute a given task at non-pre-determined time intervals. My understanding of this is that cronjobs require me to know when the task will be performed again. Thus, I was recommended to use "at."
I'm having a bit of trouble using "at." Based on some experimentation, I've found that
echo "hello" | at now + 1 minutes
will run in my terminal (with and without quotes). Running "atq" results in my computer telling me that the command is in the queue. However, I never see the results of the command. I assume that I'm doing something wrong, but the manpages don't seem to be telling me anything useful.
Thanks in advance for any help.
Besides the fact that commands are run without a terminal (output and input is probably redirected to /dev/null), your command would also not run since what you're passing to at is not echo hello but just hello. Unless hello is really an existing command, it won't run. What you want probably is:
echo "echo hello" | at now + 1 minutes
If you want to know if your command is really running, try redirecting the output to a file:
echo "echo hello > /var/tmp/hello.out" | at now + 1 minutes
Check the file later.
I am running a command to push files to Google App Engine, and it might ask me for my email and password:
$ appcfg.py update .
Application: my-cdn; version: 3. # printed out
Server: appengine.google.com. # printed out
Scanning files on local disk. # printed out
Initiating update. # printed out
Email: email#gmail.com # now it asks me...
Password:
I am running that in Ruby right now using this: %x[appcfg.py update .]. How can I fill out the email and password? I have seen something like this with capistrano:
%x[appcfg.py update .] do |channel, stream, data|
channel.send_data "#{yaml['production']['email']}\n" if data =~ /^Email:/
end
...but haven't figured out how to set that up without it.
What's the best way to fill out things the command line asks for programmatically?
Another issue is that if I run the command through ruby, I can see output as the command runs, but it never shows me the "Email: " line, it stops here:
Application: my-cdn; version: 3.
Server: appengine.google.com.
Scanning files on local disk.
Initiating update.
# ... can't see "Email: "
Thanks for the tips.
Generally, you can use Open3.popen3(command) do |input, output, error| ... end to invoke a command, write to its input stream and read from its output and error streams (you need to require "open3" first).
However that usually does not work with programs that ask for a password (because they access the terminal directly instead of simply reading from stdin). In that case, you need to use PTY (require "pty") instead of open3. PTY.getpty will spawn a shell and return an array containing the shell's output stream, input stream and pid. You can use those to invoke commands and read their input (be aware that the output you read will also include the shell prompt and the command invocation).
I am running a PowerShell script from within a batch file. The script fetches a web page and checks whether the page's content is the string "OK".
The PowerShell script returns an error level to the batch script.
The batch script is executed by ScriptFTP, an FTP automation program. If an error occurs, I can have ScriptFTP send the full console output to the administrator via E-Mail.
In the PowerShell script, I would like to output the return value from the web site if it is not "OK", so the error message gets included in the console output, and thus in the status mail.
I am new to PowerShell and not sure which output function to use for this. I can see three:
Write-Host
Write-Output
Write-Error
What would be the right thing to use to write to the Windows equivalent of stdout?
Simply outputting something is PowerShell is a thing of beauty - and one its greatest strengths. For example, the common Hello, World! application is reduced to a single line:
"Hello, World!"
It creates a string object, assigns the aforementioned value, and being the last item on the command pipeline it calls the .toString() method and outputs the result to STDOUT (by default). A thing of beauty.
The other Write-* commands are specific to outputting the text to their associated streams, and have their place as such.
I think in this case you will need Write-Output.
If you have a script like
Write-Output "test1";
Write-Host "test2";
"test3";
then, if you call the script with redirected output, something like yourscript.ps1 > out.txt, you will get test2 on the screen test1\ntest3\n in the "out.txt".
Note that "test3" and the Write-Output line will always append a new line to your text and there is no way in PowerShell to stop this (that is, echo -n is impossible in PowerShell with the native commands). If you want (the somewhat basic and easy in Bash) functionality of echo -n then see samthebest's answer.
If a batch file runs a PowerShell command, it will most likely capture the Write-Output command. I have had "long discussions" with system administrators about what should be written to the console and what should not. We have now agreed that the only information if the script executed successfully or died has to be Write-Host'ed, and everything that is the script's author might need to know about the execution (what items were updated, what fields were set, et cetera) goes to Write-Output. This way, when you submit a script to the system administrator, he can easily runthescript.ps1 >someredirectedoutput.txt and see on the screen, if everything is OK. Then send the "someredirectedoutput.txt" back to the developers.
I think the following is a good exhibit of Echo vs. Write-Host. Notice how test() actually returns an array of ints, not a single int as one could easily be led to believe.
function test {
Write-Host 123
echo 456 # AKA 'Write-Output'
return 789
}
$x = test
Write-Host "x of type '$($x.GetType().name)' = $x"
Write-Host "`$x[0] = $($x[0])"
Write-Host "`$x[1] = $($x[1])"
Terminal output of the above:
123
x of type 'Object[]' = 456 789
$x[0] = 456
$x[1] = 789
You can use any of these in your scenario since they write to the default streams (output and error). If you were piping output to another commandlet you would want to use Write-Output, which will eventually terminate in Write-Host.
This article describes the different output options: PowerShell O is for Output
What would be the right thing to use to write to the Windows equivalent of stdout?
In effect, but very unfortunately, both Windows PowerShell and PowerShell Core as of v7.2, send all of their 6(!) output streams to stdout when called from the outside, via PowerShell's CLI.
See GitHub issue #7989 for a discussion of this problematic behavior, which likely won't get fixed, so as to preserve backward compatibility.
In practice, this means that whatever PowerShell stream you send output to will be seen as stdout output by an external caller:
E.g., if you run the following from cmd.exe, you'll see no output, because the stdout redirection to NUL applies equally to all PowerShell streams:
C:\>powershell -noprofile -command "Write-Error error!" >NUL
However - curiously - if you redirect stderr, PowerShell does send its error stream to stderr, so that with 2> you can capture the error-stream output selectively; the following outputs just 'hi' - the success-stream output - while capturing the error-stream output in file err.txt:
C:\>powershell -noprofile -command "'hi'; Write-Error error!" 2>err.txt
The desirable behavior is:
Send PowerShell's success output stream (number 1) to stdout.
Send output from all other streams to stderr, which is the only option, given that between processes only 2 output streams exist - stdout (standard output) for data, and stderr (standard error) for error messages and all other types of messages - such as status information - that aren't data.
It's advisable to make this distinction in your code, even though it currently isn't being respected.
Inside PowerShell:
Write-Host is for display output, and bypasses the success output stream - as such, its output can neither be (directly) captured in a variable nor suppressed nor redirected.
Its original intent was simply to create user feedback and create simple, console-based user interfaces (colored output).
Due to the prior inability to be captured or redirected, PowerShell version 5 made Write-Host write to the newly introduced information stream (number 6), so since then it is possible to capture and redirect Write-Host output.
Write-Error is meant for writing non-terminating errors to the error stream (number 2); conceptually, the error stream is the equivalent of stderr.
Write-Output writes to the success [output] stream (number 1), which is conceptually equivalent to stdout; it is the stream to write data (results) to.
However, explicit use of Write-Output is rarely needed due to PowerShell's implicit output feature:
Output from any command or expression that isn't explicitly captured, suppressed or redirected is automatically sent to the success stream; e.g., Write-Output "Honey, I'm $HOME" and "Honey, I'm $HOME" are equivalent, with the latter not only being more concise, but also faster.
See this answer for more information.
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta
Magenta can be one of the "System.ConsoleColor" enumerator values - Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White.
The + $File.FullName is optional, and shows how to put a variable into the string.
You simply cannot get PowerShell to ommit those pesky newlines. There is no script or cmdlet that does this.
Of course Write-Host is absolute nonsense because you can't redirect/pipe from it! You simply have to write your own:
using System;
namespace WriteToStdout
{
class Program
{
static void Main(string[] args)
{
if (args != null)
{
Console.Write(string.Join(" ", args));
}
}
}
}
E.g.
PS C:\> writetostdout finally I can write to stdout like echo -n
finally I can write to stdout like echo -nPS C:\>
I saved this VBScript script to my local machine as c:\test.vbs:
WScript.StdOut.WriteLine "This is a test"
When I run it from the command line, I get this error:
---------------------------
Windows Script Host
---------------------------
Script: C:\test.vbs
Line: 1
Char: 1
Error: The handle is invalid.
Code: 80070006
Source: (null)
---------------------------
OK
---------------------------
I get this under Windows Vista (SP1) and Windows XP Pro (SP3).
This link may help you:
http://www.tech-archive.net/Archive/Scripting/microsoft.public.scripting.vbscript/2004-07/0979.html
It appears that the handle StdOut is only available when using a console host (cscript.exe) and not a windowed host (wscript.exe). If you want the code to work, you have to use cscript.exe to run it.
The post also describes how to change default behavior to run scripts with cscript and not wscript.
As described by the article in the accepted answer, my script worked when I called it from the command prompt like this:
cscript test.vbs
You can also change the default script host, so that a call to cscript is not necessary every single time. After doing that, the original command works unmodified.
cscript //h:cscript //s
You can restore the original behavior with:
cscript //h:wscript //s
Thanks!!
I submitted this solution in bug "cscript - print output on same line on console?" which I feel is related to this issue.
I use the following "log" function in my JavaScript to support either wscript or cscript environment. As you can see this function will write to standard output only if it can.
var ExampleApp = {
// Log output to console if available.
// NOTE: Script file has to be executed using "cscript.exe" for this to work.
log: function (text) {
try {
// Test if stdout is working.
WScript.stdout.WriteLine(text);
// stdout is working, reset this function to always output to stdout.
this.log = function (text) { WScript.stdout.WriteLine(text); };
} catch (er) {
// stdout is not working, reset this function to do nothing.
this.log = function () { };
}
},
Main: function () {
this.log("Hello world.");
this.log("Life is good.");
}
};
ExampleApp.Main();