c - 使用 fgets() 和 echo 用 C system() 调用封装单行 AppleScript

标签 c macos scripting terminal applescript

如果我将 AppleScript 压缩成一行,我如何封装它以在 C 程序的 echo system 调用中运行?我尝试过的所有格式都会导致错误:(单引号、双引号、各种括号等...)

如果不清楚,我有一个使用 fgets() 来捕获输入的 C 程序。当我尝试在系统命令中回显时,例如 echo ' && foo bar && $? ' 它通常有效。但是,如果我想直接在 AppleScript 中 echo,我似乎无法将格式设置下来。有什么想法吗?

FWIW 这是我正在尝试的:

echo ' && "osascript -e 'tell application "Terminal"' -e 'do script "foo bar"' -e 'end tell'"&& $?'

上面的示例回显单引号中包含的所有内容并“打印”它,但不执行它。我已经尝试了很多关于引号等的变体,但都无济于事。此外,在 osascript ... 'end tell' 之间直接在终端中运行时有效。

感谢任何帮助!

编辑

这是一段 C 代码:

    char comment[80];
    char cmd[120];
    fgets(comment, 80, stdin);
    sprintf(cmd, "echo '%s %s' >> reports.log", comment, now());
    system(cmd);

编辑二...将标题更改为更准确

最佳答案

好的!根据您的意见,我会像这样重写您的问题:

How to trick system("echo %s") into running AppleScript?

I'm trying to push the limits of system() to understand why it is important to be careful with its use in C. This sample program is presented in a book on C:

#include <stdio.h>
#include <stdlib.h>

char* now() {
    return "yyyy-mm-dd";
}

int main() {
    char comment[80];
    char cmd[120];
    fgets(comment, 80, stdin);
    sprintf(cmd, "echo '%s %s' >> reports.log", comment, now());
    return system(cmd);
}

I can "echo out" of the program and execute most bash scripts with the program by typing ' && pwd && '. Now I want to figure out how to do something similar, but by using AppleScript instead of bash. I’m trying this:

' && "osascript -e 'tell application "Terminal"' -e 'do script "foo bar"' -e 'end tell'" && '

The osascript ... 'end tell' command works when run directly in the terminal, but it’s not executing properly. I have tried many variations on quotes, etc, to no avail.

那么,我的回答是:


为了更容易准确地调试正在运行的命令,让我们将命令回显到终端:

#include <stdio.h>
#include <stdlib.h>

char* now() {
    return "yyyy-mm-dd";
}

int main() {
    char comment[80];
    char cmd[120];
    fgets(comment, 80, stdin);
    sprintf(cmd, "echo '%s %s' >> reports.log", comment, now());

    /* for debugging */
    printf("executing %s\n", cmd);

    return system(cmd);
}

现在让我们试试看:

$ gcc -c prog.c -o prog
$ ./prog
' && osascript -e 'tell application "Terminal"' -e 'do script "date"' -e 'end tell'" && '
executing echo '' && osascript -e 'tell application "Terminal"' -e 'do script "date"' -e 'end t yyyy-mm-dd' >> reports.log

嗯!它不知何故被截断为 end t 而不是 end tell'"&& '。等等,输入缓冲区有多大?80 个字符?这就是问题所在!您正在尝试的 AppleScript 命令在语法上是正确的,但对于输入缓冲区来说太长了,并且被截断了。

消除所有空格并使用 little-known bash feature要嵌入换行符,我只能勉强将 AppleScript 压缩成 77 个字符:

'&&osascript -e$'tell application "Terminal"\ndo script "date"\nend tell'&& '

由于 80 个字符的缓冲区末尾需要一个空终止符,因此它实际上只能容纳 79 个字符。因此,使用这个特定的 AppleScript 命令,您可以在终端中运行最多 6 个字符长的 shell 命令……


我对我认为是你原来的问题——如何从 C 调用多行 AppleScript——的回答仍然是:


命令行参数可以包含换行符。您可以像这样从 bash 运行整个 AppleScript:

$ osascript -e '
tell application "Terminal"
    do script "date"
end tell'

bash 暂停等待结束 ',然后将整个脚本作为单个参数传递。

你可以在 C 中做类似的事情,只是多一点引用:

#include <stdio.h>

int main() {
    system("osascript -e '\n"
            "tell application \"Terminal\"\n"
            "   do script \"date\"\n"
            "end tell'\n");
    return 0;
}

关于c - 使用 fgets() 和 echo 用 C system() 调用封装单行 AppleScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14513447/

相关文章:

macos - 获取 Mac OS X 上的当前堆栈跟踪

macos - 使用 NSPopUpButtonCell 时在 NSTableView 中获取重复的标题按钮单元格

bash - 命令中的 Shell 变量替换

scripting - 在Powershell中,将两个表合并为一个的最佳方法是什么?

c - Lint 警告 506 : prio3: Constant value Boolean

c++ - 如何使用 ODBC 批量获取或插入行? (在 C 或 C++ 中)

c - C中梯形数值积分的实现

c - Apache 可移植运行时教程?

cocoa - 轻微干扰 : NSMatrix cell order tag. 1- 第一项,0- 第二项

ruby - 您是否已将 makefile 替换为 ruby​​ 脚本?