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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:56:32  来源:igfitidea点击:

How to execute terminal command in swift?

node.jsswiftbashmacosterminal

提问by aharo vishinsky

I am new toSswift. How can I run this process from Swift code?

我是 Sswift 的新手。我如何从 Swift 代码运行这个过程?

  1. open Terminal window
  2. execute cd Desktop/firebase-mac
  3. execute npm start
  1. 打开终端窗口
  2. 执行 cd Desktop/firebase-mac
  3. 执行 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 scriptas: ./swsh
  • 打开终端
  • 类型 cd ~/Desktop
  • chmod 755 swsh
  • 并运行你swift script的:./swsh

You will get output like:

你会得到如下输出:

Sat Mar 25 14:31:39 CET 2017

Edit your swshand 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 swshexecuted the /usr/bin/env, (with the argument date)
  • and the /usr/bin/envfinds the command date
  • and executed it
  • swsh执行的/usr/bin/env,(用参数date
  • 然后/usr/bin/env找到命令date
  • 并执行它

Now, create another file in the ~/Desktopand name it as from_swift.

现在,在 中创建另一个文件~/Desktop并将其命名为from_swift.

Add into it

添加进去

echo "Today's date is $(date)"

change the file swshchange the shellline to:

更改文件swshshell行更改为:

let output = shell(launchPath: "./from_swift", arguments: [ ])

Note, the ./from_swift- using relative path to .(we are in the ~/Desktopdirectory). 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_swiftis 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_swiftis 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 scriptedit the from_swiftscript as:

这是因为这from_swift是一个脚本(不是编译后的二进制文件),所以操作系统需要知道哪个二进制文件应该解释脚本内容。因为这是shell scriptfrom_swift脚本编辑为:

#!/bin/sh
echo "Today's date is $(date)"

Note the added "shebang" line: #!/bin/sh. Run the swift ./swshand will get

请注意添加“认领”行:#!/bin/sh。运行 swift./swsh并会得到

Today's date is Sat Mar 25 14:50:23 CET 2017

Horray, you executed your 1st bashscript from swift. ;)

哎呀,你bashswift. ;)

Of course, you can use the /usr/bin/envin the shebang, so now change, the content of the from_swiftfor 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 ./swshand 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 ./swshfile, 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 shebangline
    • and must be executable using chmod 755 /path/to/script.file
  • 编译的二进制文件
  • 或脚本文件,但脚本文件
    • 必须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/shand 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.

但请考虑,如果应用程序被沙盒化,文字路径将不起作用。