I am not sure whether to post this on StackOverflow or AskUbuntu, based on my current understanding the problem lies in my lack of understanding of rights and execution permissions/handling within Ubuntu instead of Java programming approach, hence I thought this was the place to ask.
While succesfully executing terminal commands generated in a java project that is compiled to a commandUbuntu.jar
, I found a command that does not execute as I thought it would. I installed taskwarrior 2.5 and I am trying to create a custom user defined attribute (UDA) using Java. The command(s) is/are:
printf 'y\n' | sudo task config uda.newTestSort.type numeric
printf 'y\n' | sudo task config uda.newTestSort.label nTSort
reproduction Taskwarrior can be installed with:
sudo apt update && sudo apt upgrade
sudo apt install task
You can add 2 tasks with:
task add this is the test task one description
task add test task two
Attached is a MWE created to just run the 2 commands, it can be compiled to .jar
in eclipse by clicking: file>export>select node Java>Select Runnable JAR file>Click next>Launch Configuration:
CommandLinux - LearnToSayYesToLinux>Chose an export location and name, e.g.
c:/commandLinux.jar`>Package required libraries into generated JAR>Click Finish.
Then it can be run in Ubuntu with:
cd /mnt/c/commandLinux.jar
java -jar commandLinux.jar
MWE:
package learnToSayYesToLinux;
import java.io.*;
import java.util.ArrayList;
public class CommandLinux {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Test create a custom UDA
createUDA("abstractSort","aSort","numeric");
System.exit(0);
}
/**
* Method creates a taskwarrior user defined Attribute if the data type is correct
* Thows error datatype is not correct.
* TODO: write proper exception
* @param udaName
* @param label
* @param type
*/
private static void createUDA(String udaName, String label,String type) {
char vd = (char)124; //vertical dash: |
char bs = (char)92; //backslash: \
String[] commands = new String[2];
//Check if the datatype is correct for taskwarrior:
if (type.equals("numeric") || type.equals("string") || type.equals("date") || type.equals("duration")){
commands[0]="printf 'y"+bs+"n' "+vd+" sudo task config uda."+udaName+".type "+type;
commands[1]="printf 'y"+bs+"n' "+vd+" sudo task config uda."+udaName+".label "+ label;
runCommands(commands[0], false);
runCommands(commands[1], false);
System.out.println("Ran:"+commands[0]);
System.out.println("Ran:"+commands[1]);
//Trow exception if the datatype is not correct.
}else {
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static ArrayList<ArrayList<String>> runCommands(String command,boolean ignoreOutput) {
String s = null;
String outputLines=null;
ArrayList<String> goodExecutionOutput=new ArrayList<String>();
ArrayList<String> errorExecutionOutput=new ArrayList<String>();
ArrayList<ArrayList<String>> returnLists = new ArrayList<ArrayList<String>>();
try {
// run the Unix "task nice0" command
Process p = Runtime.getRuntime().exec(command);
BufferedReader brGood = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader brError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
// get output
if (!ignoreOutput) {
while ((s = brGood.readLine()) != null) {
System.out.println("Adding:"+s);
goodExecutionOutput.add(s);
}
// get the error message
while ((s = brError.readLine()) != null) {
errorExecutionOutput.add(s);
}
}
}
catch (IOException e) {
System.out.println("Error: ");
e.printStackTrace();
System.exit(-1);
}
//Merge outputLists and return
returnLists.add(goodExecutionOutput);
returnLists.add(errorExecutionOutput);
return returnLists;
}
}
Result
If the command is executed by the .jar
file it returns:
ationAndSystems/Taskwarrior/customSortServerV4$ java -jar testCommand.jar
Adding:'y
Adding:'
Adding:'y
Adding:'
Ran:printf 'y\n' | sudo task config uda.newTestSort.type numeric
Ran:printf 'y\n' | sudo task config uda.newTestSort.label nTSort
If I run the command manually it returns:
$ printf 'y\n' | sudo task config uda.newTestSort.type numeric
Are you sure you want to change the value of 'uda.newTestSort.type' from 'numeric' to 'numeric'? (yes/no) Config file /home/a/.taskrc modified.
$ printf 'y\n' | sudo task config uda.newTestSort.label nTSort
Are you sure you want to change the value of 'uda.newTestSort.label' from 'nTSort' to 'nTSort'? (yes/no) Config file /home/a/.taskrc modified.
The interpretation/testing of this result is discussed at "Verification".
Result attempt 2 As suggested in the comments: Modifying lines 36 and 37 of the MWE to:
commands[0]="yes yes "+vd+" sudo task config uda."+udaName+".type "+type;
commands[1]="yes yes "+vd+" sudo task config uda."+udaName+".label "+ label;
Yields an infinite repetition (until Stack Overflow occurs) of:
Adding:yes | sudo task config uda.testSortA.type numeric
If I set the boolean ignoreOutput
to false when I call method runCommands()
it returns:
Ran:yes yes | sudo task config uda.testSortA.type numeric
Ran:yes yes | sudo task config uda.testSortA.label tSortA
After verification I concluded this command did not effectively add a new UDA.
Verification If I manually enter them in Ubuntu 16.04 they work fine. I test it by entering:
sudo task 2 modify newTestSort:29
If the UDA does not yet exist in taskwarrior it will interpret that statement as: "modify the description of task 2". However if the UDA newTestSort
does exist and is of type numeric
it will set the task 2 uda newTestSort
(labelled with nTSort
) to 2. These two results are read in the output of command sudo task 2
, first before creation of the UDA to verify the UDA does not yet exist by checking if the task description has been changed to newTestSort:29
and a second time, after entering the 2 UDA creation commands listed above, to verify the UDA is indeed created, by checking if the new UDA nTSort
is listed with value 29.
Question: How do I automatically answer "yes" to the prompt below without creating an additional file, using Java?
Are you sure you want to change the value of 'uda.newTestSort.type' from 'numeric' to 'numeric'? (yes/no) Config file /home/a/.taskrc modified.
Current understanding
The answer by lesmana explains that the vertical dash connects the input for what is right of the dash with the output of what is left of the dash. It says the output of yes
is an endless stream of y
's, so afther the command asks for input it would stream those y
-s into that question. I currently do not understand why it would stop doing that.
Another doubt I have is that the command might be interpreted differently compared to when it is manually entered due to the way it is given from a .jar
file to a process instead of entered in terminal. This might cause for a different interpretation/meaning of the |. I am looking into how the commands are interpreted from a .jar
file by ubuntu.
Additionally I checked whether it was a problem with the rights that the .jar
file has, so I tried to execute the suggested command of attempt 2 with:
sudo java -jar commandUbuntu.jar
But after verification I concluded that that did not allow for adding a new UDA from Java.
yes yes
to print endlessyes
and noty
. Anyways, you should clarify what happens when you useprintf 'y\n' | ...
oryes | ...
yes yes
is required to print an endless stream ofyes
, and not for example a singleyes
, or tripleyes
? I will try it and include the results of both my described attempt and of your suggestion.yes
defines its output. Default isy
. See the manual:man yes
-->Repeatedly output a line with all specified STRING(s), or 'y'.
.printf 'yes yes "+bs+"n'
, use justyes yes
yes
followed by a space followed by the command.