I have a program written in swift and I was wondering how I could reference a variable (String) in my terminal command.
This is what I have tried but I am not having any success.
var clientUsed : String = "Safari"
var killApp: NSAppleScript?
let killCommand = "do shell script \"killall " + clientUsed\"
killApp = NSAppleScript(source:killCommand)
How do I structure this correctly?
The command should say the following:
killall Safari
Where safari is a variable chosen by the user.
I assume anyone with swift or obj-c knowledge will be able to help me with this.
The easiest way is via string interpolation. Inside your string literal, enclose a variable in \() to have it’s string representation inserted at that point:
let killCommand = "do shell script \"killall \(clientUsed)\""
Your original idea of using + would also work (less neat though), but you needed to add an additional string literal on the end:
let killCommand = "do shell script \"killall " + clientUsed + "\""
Related
In my Makefile I have defined a variable
VAR = -Ddef1 -Ddef2 -Ddef3
I'd like to launch make like this
make VAR+=-Ddef4 -Ddef5
But the space messes things up. How can I set VAR to a list of values, like it's possible to do inside the Makefile? Thanks for tips.
In your Makefile:
VAR = -Ddef1 -Ddef2 -Ddef3 $(EXTRAVAR)
On the command line:
make EXTRAVAR="-Ddef4 -Ddef5"
As frequently with the shell, tokens with spaces must be quoted. On the command line make FOO+= does the same as make FOO=. It does not append, it overwrites (in your case). Thus the trick with a second variable EXTRAVAR.
I want to run a bat file used to compile sass to css from within a Kotlin program, on a Windows machine. I had everything working using Runtime.exec until I switched to a Windows account that had a space in the username. From what I read, I read that using ProcessBuilder would make this easier. It seems that even with ProcessBuilder I still can't get it to work, no matter what I try.
Here is my code so far
val commands = mutableListOf(
"cmd",
"/c",
"C:\\Users\\John Doe\\VCS\\test\\tools\\sass\\windows\\dart-sass\\sass.bat",
"--no-source-map",
"C:\\Users\\John Doe\\VCS\\test\\src\\main\\sass\\global.scss",
"global.css"
)
val processBuilder = ProcessBuilder(commands)
val process = processBuilder.start()
...
The error I get is 'C:\Users\John' is not recognized as an internal or external command, operable program or batch file. It doesn't help if I surround the strings that have spaces with \".
If I remember correctly, all windows files and folders that have a space in the name have a matching short name in the old 8.3 format replacing additional space and other characters with a tilde (~) and a number.
So whatever is returning you the path for the .bat and .sscs files could return the full filename in that format?
Doesn't solve the problem but avoids it instead, I admit.
Also means you won't get busted when someone puts a space in the filename (OK, unlikely, but still something better to deal with from the start).
Consider something along the lines of the top 2 answers on this superuser thread
This is actually a Windows cmd issue. The question here shows that in cmd, in addition to quoting the file paths, you also have to quote the entire part of the command line text after the /c switch.
I don't know if this is the best way to do it in ProcessBuilder, but I was able to get it to work with the following code.
"cmd.exe",
"/c",
"\"\"C:/Users/John Doe/VCS/test/tools/sass/windows/dart-sass/sass.bat\" "
+ "--no-source-map "
+ "\"C:/Users/John Doe/VCS/test/src/main/sass/global.scss\" "
+ "\"global.css\"\""
I am trying to prompt the user of my .jl file to enter user entered multiple destinations.
Basically I need the user to give an input & an output. I know in java you would use a scanner, or accept arguments when it is compiled in the command line. I am fine with either option. From what I have found looking through the Julia Documentation I think I could accomplish the first way of assigning a variable to the readline function.
(String)in = (String)Readline(STDIN)
From my understanding the variable 'in' should now contain a String of the user's input. I am encountering an error, in that when I compile my .jl code, because my command prompt does not stop to read user input, and just finishes reading the .jl code.
The first item to note in the code in your question is:
(String)in = (String)Readline(STDIN)
Julia 1.0.0 now uses stdin instead of STDIN.
Next, the (String) typecasting is not something you need or want to do in Julia.
Thus your code could read (though we get an error):
julia> in = readline(stdin)
This is a test.
ERROR: cannot assign variable Base.in from module Main
So variable in is in conflict with a Julia Base.in variable. Just use a another variable name.
julia> response = readline(stdin)
This is a test.
"This is a test"
This code is now working, but it has no prompt. Your answer provides an example input function with a prompt which you defined like this:
julia> function input(prompt::AbstractString="")
print(prompt)
return chomp(readline())
end
input (generic function with 2 methods)
The chomp function removes a single trailing \n newline character from the input string. Docs here.
Example use of the function here:
julia> input_file = input("Please enter input file name: ")
Please enter input file name: Data.txt
"Data.txt"
julia> output_file = input("Please enter output file name: ")
Please enter output file name: Output.txt
"Output.txt"
Command Line Args Method
As the docs point out, to just print out the arguments given to a script, you can do something like this:
println("Arguments passed to ", PROGRAM_FILE, ":")
for arg in ARGS
println(arg)
end
Here is an example of above code running on the Windows command line:
c:\OS_Prompt>julia PrintArgs.jl Data.txt Output1.txt Output2.txt Output3.txt
Arguments passed to PrintArgs.jl:
Data.txt
Output1.txt
Output2.txt
Output3.txt
You can also print out the script file name as shown, PrintArgs.jl.
After searching & testing I found one solution and decided to reply to it here. I had to declare my own function to be able to get the program to accept user input.
function input(prompt::AbstractString="")
print(prompt)
return chomp(readline())
end
I am not sure what the chomp function does, but I know it works for what I was asking. I am still curious if you can do something in Julia similar to java and C String args[], in which you pass extra information while you are telling your command to run. Something like the following.
Julia testFile.jl goHere.txt lookHere.txt
I have a typescript project set up that is being built with GruntJS using the typescript plugin. I also have a Visual Studio project that I'd like to be able to invoke the build process from.
My first attempt at doing this was adding an <Exec> task to the BeforeBuild target in visual studio, with the <Exec> task configured like this:
<Exec Command="grunt --no-color typescript" />
This runs the build fine, however, when errors are output from Grunt and they populate the Error List in VS, the filename is incorrectly listed as EXEC.
Looking at the Exec Documentation I see that CustomErrorRegularExpression is a parameter to the command, but I can't quite grasp how to use it to solve my problem.
I messed around with it a bit and managed to change the reported filename to my .jsproj file, which is also incorrect. Looking at this post I tried forming my own regex:
<Exec CustomErrorRegularExpression="\.ts\([0-9]+,[0-9]+\):(.*)" Command="grunt --no-color typescript" IgnoreExitCode="true" />
Does anyone have any experience using this command with this parameter to achieve this sort of thing? I think maybe part of the problem is that grunt is printing out errors in two lines?
You are correct about the Exec task only processing single line messages. In addition it also uses Regex.IsMatch to evaluate the error/warning condition, without making use of the pattern's capture groups.
I was not able to find a way to work around this via MSBuild, but the changes to correct the problem were easy to make directly in the grunt task.
I'm using the grunt-typescript task from: https://www.npmjs.org/package/grunt-typescript.
There were 3 trivial changes necessary to make this work.
1) Replace the output utility methods near the top of tasks/typescript.js:
/* Remove the >> markers and extra spacing from the output */
function writeError(str) {
console.log(str.trim().red);
}
function writeInfo(str) {
console.log(str.trim().cyan);
}
2) Replace Compiler.prototype.addDiagnostic to write the file and error data on the same line:
Compiler.prototype.addDiagnostic = function (diagnostic) {
var diagnosticInfo = diagnostic.info();
if (diagnosticInfo.category === 1)
this.hasErrors = true;
var message = " ";
if (diagnostic.fileName()) {
message = diagnostic.fileName() +
"(" + (diagnostic.line() + 1) + "," + (diagnostic.character() + 1) + "): ";
}
this.ioHost.stderr.Write(message + diagnostic.message());
};
Once these changes are made, you no longer need the CustomErrorRegularExpression to be set on your Exec task, and your build output should display the error text including the correct source file with line and column information.
AIR doesn't permit launching .bat files as a native process directly, so apparently i'm suppose to set CMD.exe as my startupInfo executable and pass my .bat file and it's arguments.
i can't get it to work, so i'm hoping it's a syntax problem. here is my code:
var testStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
testStartupInfo.executable = new File("C:\\WINDOWS\\system32\\cmd.exe");
var processArguments:Vector.<String> = new Vector.<String>();
processArguments[0] = "/c";
processArguments[1] = "\"C:\\Documents and Settings\\Administrator\\Desktop\\Test\\Test.bat\"";
processArguments[2] = "-testBatPeram1";
processArguments[3] = "-testBatPeram2";
processArguments[4] = "Peram3";
processArguments[5] = "C:\\Documents and Settings\\Administrator\\Desktop\\SaveText.txt";
testStartupInfo.arguments = processArguments;
var test:NativeProcess = new NativeProcess();
test.start(testStartupInfo);
the batch file and its parameters work fine if i manually write them in the command line prompt, so i don't know why nothing is happening when launched from AIR.
Ok i think that by now (3 months later) you have realized that this doesn't work because your bat file path contains spaces.
Have you find any workaround or solution or something?
I have a good approximation that could be enough for you:
Instead of passing parameters to your bat try writing to it through its stdinput.
I mean, instead of passing parameters when calling your bat, treat that info as a variable read in execution.