bash 如何快速执行终端命令?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43014600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to execute terminal command in swift?
提问by aharo vishinsky
I am new toSswift. How can I run this process from Swift code?
我是 Sswift 的新手。我如何从 Swift 代码运行这个过程?
- open Terminal window
- execute
cd Desktop/firebase-mac
- execute
npm start
- 打开终端窗口
- 执行
cd Desktop/firebase-mac
- 执行
npm start
What I am actually trying to do is to start Node server on click from Swift code.
我实际上想要做的是从 Swift 代码点击启动 Node 服务器。
回答by jm666
Full examples:
完整示例:
- go to some directory, let say
Desktop
- Create a file with name
swsh
, and add into it (plaintext, not rtf, or doc)
- 转到某个目录,比如说
Desktop
- 创建一个名为 name 的文件
swsh
,并将其添加到其中(纯文本,而不是 rtf 或 doc)
#!/usr/bin/env xcrun swift
import Foundation
func shell(launchPath: String, arguments: [String]) -> String {
let process = Process()
process.launchPath = launchPath
process.arguments = arguments
let pipe = Pipe()
process.standardOutput = pipe
process.launch()
let output_from_command = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: String.Encoding.utf8)!
// remove the trailing new-line char
if output_from_command.characters.count > 0 {
let lastIndex = output_from_command.index(before: output_from_command.endIndex)
return output_from_command[output_from_command.startIndex ..< lastIndex]
}
return output_from_command
}
let output = shell(launchPath: "/bin/date", arguments: [ ])
print(output)
Save, and:
保存,然后:
- open the Terminal
- type
cd ~/Desktop
- use
chmod 755 swsh
- and run your
swift script
as:./swsh
- 打开终端
- 类型
cd ~/Desktop
- 用
chmod 755 swsh
- 并运行你
swift script
的:./swsh
You will get output like:
你会得到如下输出:
Sat Mar 25 14:31:39 CET 2017
Edit your swsh
and change the shell(...
line to:
编辑您的swsh
并将该shell(...
行更改为:
let output = shell(launchPath: "/usr/bin/env", arguments: [ "date" ])
run it and again will get the date, but now:
再次运行它会得到日期,但现在:
- the
swsh
executed the/usr/bin/env
, (with the argumentdate
) - and the
/usr/bin/env
finds the commanddate
- and executed it
- 的
swsh
执行的/usr/bin/env
,(用参数date
) - 然后
/usr/bin/env
找到命令date
- 并执行它
Now, create another file in the ~/Desktop
and name it as from_swift
.
现在,在 中创建另一个文件~/Desktop
并将其命名为from_swift
.
Add into it
添加进去
echo "Today's date is $(date)"
change the file swsh
change the shell
line to:
更改文件swsh
将shell
行更改为:
let output = shell(launchPath: "./from_swift", arguments: [ ])
Note, the ./from_swift
- using relative path to .
(we are in the ~/Desktop
directory). Run the swift program:
注意,./from_swift
- 使用相对路径.
(我们在~/Desktop
目录中)。运行 swift 程序:
./swsh
Output:
输出:
2017-03-25 14:42:20.176 swift[48479:638098] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'launch path not accessible'
Of course, the script from_swift
is notexecutable yet. So execute:
当然,该脚本from_swift
尚不可执行。所以执行:
chmod 755 from_swift
# and run
./swsh
Again error:
再次报错:
2017-03-25 14:45:38.523 swift[48520:639486] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't posix_spawn: error 8'
This is because the from_swift
is a script (not a compiled binary), so the operating system need to know which binary should interpret the script content. Because this is an shell script
edit the from_swift
script as:
这是因为这from_swift
是一个脚本(不是编译后的二进制文件),所以操作系统需要知道哪个二进制文件应该解释脚本内容。因为这是shell script
将from_swift
脚本编辑为:
#!/bin/sh
echo "Today's date is $(date)"
Note the added "shebang" line: #!/bin/sh
. Run the swift ./swsh
and will get
请注意添加“认领”行:#!/bin/sh
。运行 swift./swsh
并会得到
Today's date is Sat Mar 25 14:50:23 CET 2017
Horray, you executed your 1st bash
script from swift
. ;)
哎呀,你bash
从swift
. ;)
Of course, you can use the /usr/bin/env
in the shebang
, so now change, the content of the from_swift
for example to:
当然,您可以在/usr/bin/env
中使用shebang
,因此现在将 中的内容更改from_swift
为:
#!/usr/bin/env perl
use strict;
use utf8;
use English;
binmode STDOUT, ":utf8";
printf "The $EXECUTABLE_NAME (ver:$PERL_VERSION) runs me: The /usr/bin/perl (ver:v5.18.2) runs me: ./from_swift
I ?? perl!
\n";
printf "I ?? perl!\n";
Run the ./swsh
and will get:
运行./swsh
将得到:
$ uname -a
Darwin nox.local 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64
$ swift --version
Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)
Target: x86_64-apple-macosx10.9
NOTE, we changed nothingin the ./swsh
file, just the script file ./from_swift
!
注意,我们改变什么的在./swsh
文件中,只是脚本文件./from_swift
!
All the above done using:
以上所有使用:
#!/bin/sh
cd $HOME/Desktop/firebase-mac
npm start
So, it is easy to create and execute anyscript. So, you can enter into your ~/Desktop/from_swift
因此,很容易创建和执行任何脚本。所以,你可以进入你的~/Desktop/from_swift
func run(_ cmd: String) -> String? {
let pipe = Pipe()
let process = Process()
process.launchPath = "/bin/sh"
process.arguments = ["-c", String(format:"%@", cmd)]
process.standardOutput = pipe
let fileHandle = pipe.fileHandleForReading
process.launch()
return String(data: fileHandle.readDataToEndOfFile(), encoding: .utf8)
}
It is possible to do directlyfrom the swsh
, (Jens Meder proposed), but using this you got very easy method executing anything from the given script file.
可以直接从swsh
,(Jens Meder 建议)执行,但是使用它您可以很容易地从给定的脚本文件中执行任何操作。
Just remember: the process.launch()
executes either:
请记住:process.launch()
执行以下任一项:
- compiled binaries
- or script files, but the script files
- musthave the
shebang
line - and must be executable using
chmod 755 /path/to/script.file
- musthave the
- 编译的二进制文件
- 或脚本文件,但脚本文件
- 必须有
shebang
行 - 并且必须是可执行的
chmod 755 /path/to/script.file
- 必须有
回答by Jens Meder
You can just use the following code snippet, e.g., run("npm start")
. It will execute the command on the default shell /bin/sh
and return the output as a String
.
您可以只使用以下代码片段,例如,run("npm start")
. 它将在默认 shell 上执行命令/bin/sh
并将输出作为String
.
Process.launchedProcess(launchPath: "/Users/aharon/Desktop/firebase-mac/npm", arguments: ["start"])
If you want to use a different bash then just replace the launchPath
, e.g., for Zsh it would be /bin/zsh
.
如果您想使用不同的 bash,那么只需替换 . launchPath
,例如,对于 Zsh,它将是/bin/zsh
.
回答by vadian
To launch a process passing one argument you simply need one line:
要启动传递一个参数的进程,您只需要一行:
##代码##But consider that the literal path does not work if the application is sandboxed.
但请考虑,如果应用程序被沙盒化,文字路径将不起作用。