Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java将bash脚本分解为最小的工作块_Java_Regex_Bash - Fatal编程技术网

如何使用Java将bash脚本分解为最小的工作块

如何使用Java将bash脚本分解为最小的工作块,java,regex,bash,Java,Regex,Bash,我想编写一个Java方法,将bash脚本读入单个字符串对象,然后将该字符串分解为最小的字符串命令数组,这样我就可以一次执行一个命令。我遇到的问题是,我需要保持块语句(例如if和while以及输入重定向)完好无损,也就是说,不要进一步分解它们 例如,下面的bash脚本: ./configure --sbindir=/lib/security \ --docdir=/usr/share/doc/Linux-PAM-1.1.3 \ --enable-re

我想编写一个Java方法,将bash脚本读入单个字符串对象,然后将该字符串分解为最小的字符串命令数组,这样我就可以一次执行一个命令。我遇到的问题是,我需要保持块语句(例如if和while以及输入重定向)完好无损,也就是说,不要进一步分解它们

例如,下面的bash脚本:

./configure --sbindir=/lib/security \
            --docdir=/usr/share/doc/Linux-PAM-1.1.3 \
            --enable-read-both-confs &&

make

install -v -m755 -d /etc/pam.d &&

cat > /etc/pam.d/other << "EOF"
auth     required       pam_deny.so
account  required       pam_deny.so
password required       pam_deny.so
session  required       pam_deny.so
EOF

rm -rfv /etc/pam.d

make install &&
chmod -v 4755 /lib/security/unix_chkpwd &&
mv -v /lib/security/pam_tally /sbin &&
mv -v /lib/libpam{,c,_misc}.la /usr/lib &&
sed -i 's| /lib| /usr/lib|' /usr/lib/libpam_misc.la &&
if [ -L /lib/libpam.so ]; then
   for LINK in libpam{,c,_misc}.so; do
       ln -v -sf ../../lib/$(readlink /lib/${LINK}) /usr/lib/${LINK} &&
       rm -v /lib/${LINK}
   done
fi

echo done











这可以使用正则表达式或使用Java的其他方法来实现吗


即使是一些伪代码也是受欢迎的。

正则表达式对于这一点是不够的,您需要正确地解析语法,以获得可靠工作的东西

解析shell脚本一点也不容易(AFAIK没有正式语法)

一旦完成了解析,执行“逐块”通常不会起作用。您需要跟踪环境变量更改、当前目录更改等


话虽如此,你有没有看过这样的东西?

你真的需要一个解析器

看看这个项目,它听起来和你想做的非常相似


他们似乎已经构建了您所需的所有基本组件

这就是我目前得到的。我还没有完全测试过它

String compoundCommand = null;
ArrayList<String> commandList = new ArrayList<String>();
String list = "";
int count = 0;

ArrayList<String> splitBashScript(String script) {
    script = script.replaceAll("\\\\\n", "");
    script = script.replaceAll("([^;]);([^;])", "$1\n$2");
    String[] lines = Pattern.compile("[ \t]*\n", Pattern.MULTILINE).split(script);
    String delimiter = null;
    for (String line : lines) {
        if (!line.isEmpty()) {
            if (compoundCommand == null) {
                if (line.matches(".*<<.*")) {
                    compoundCommand = "here";
                    delimiter = line.replaceFirst(".*<< *", "").replaceAll("\"", "");
                    list += line;
                } else if (line.matches("[ \t]*for[ \t]*.*")) {
                    compoundCommand = "for";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*select[ \t]*.*")) {
                    compoundCommand = "select";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*case[ \t]*.*")) {
                    compoundCommand = "case";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*if[ \t]*.*")) {
                    compoundCommand = "if";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*while[ \t]*.*")) {
                    compoundCommand = "while";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*until[ \t]*.*")) {
                    compoundCommand = "until";
                    count++;
                    list += line;
                } else if (list.isEmpty()) {
                    commandList.add(line.replaceFirst("[ \t]*&&$", ""));
                }
            } else if (compoundCommand.equals("here")) {
                list += "\n" + line;
                if (line.matches(delimiter)) {
                    compoundCommand = null;
                    commandList.add(list.replaceFirst("[ \t]*&&$", ""));
                    list = "";
                }
            } else if (compoundCommand.equals("for")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("select")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("case")) {
                compound(line, "case", "esac");
            } else if (compoundCommand.equals("if")) {
                compound(line, "if", "fi");
            } else if (compoundCommand.equals("while")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("until")) {
                compound(line, "(for|select|while|until)", "done");
            }
        }
    }
    return commandList;
}

void compound(String line, String start, String end) {
    list += "\n" + line;
    if (line.matches("[ \t]*" + start + "[ \t]*.*")) {
        count++;
    }
    if (line.matches("[ \t]*" + end + "[ \t]*.*")) {
        count--;
    }
    if (count == 0) {
        compoundCommand = null;
        commandList.add(list.replaceFirst("[ \t]*&&$", ""));
        list = "";
    }
}
String compoundCommand=null;
ArrayList commandList=新建ArrayList();
字符串列表=”;
整数计数=0;
ArrayList splitBashScript(字符串脚本){
script=script.replaceAll(“\n”,”);
script=script.replaceAll(([^;]);([^;]),“$1\n$2”);
String[]line=Pattern.compile(“[\t]*\n”,Pattern.MULTILINE).split(脚本);
字符串分隔符=null;
用于(字符串行:行){
如果(!line.isEmpty()){
if(compoundCommand==null){

如果(line.matches)(".*我的代码的执行部分已经很好地工作了,因为环境变量更改、当前目录更改等都得到了处理。这一切都是在执行bash的单个进程下完成的,但是在不存在bash进程的情况下,它还具有在每个命令后返回状态代码的附加功能。这将分解为更小的块s是个不错的选择。我访问了jbash网站。我不确定这是否符合我的总体目标。谢谢。
make
install -v -m755 -d /etc/pam.d
cat > /etc/pam.d/other << "EOF"
auth     required       pam_deny.so
account  required       pam_deny.so
password required       pam_deny.so
session  required       pam_deny.so
EOF
rm -rfv /etc/pam.d
make install
chmod -v 4755 /lib/security/unix_chkpwd
mv -v /lib/security/pam_tally /sbin
mv -v /lib/libpam{,c,_misc}.la /usr/lib
sed -i 's| /lib| /usr/lib|' /usr/lib/libpam_misc.la
if [ -L /lib/libpam.so ]
 then
   for LINK in libpam{,c,_misc}.so; do
       ln -v -sf ../../lib/$(readlink /lib/${LINK}) /usr/lib/${LINK} &&
       rm -v /lib/${LINK}
   done
fi
echo done
String compoundCommand = null;
ArrayList<String> commandList = new ArrayList<String>();
String list = "";
int count = 0;

ArrayList<String> splitBashScript(String script) {
    script = script.replaceAll("\\\\\n", "");
    script = script.replaceAll("([^;]);([^;])", "$1\n$2");
    String[] lines = Pattern.compile("[ \t]*\n", Pattern.MULTILINE).split(script);
    String delimiter = null;
    for (String line : lines) {
        if (!line.isEmpty()) {
            if (compoundCommand == null) {
                if (line.matches(".*<<.*")) {
                    compoundCommand = "here";
                    delimiter = line.replaceFirst(".*<< *", "").replaceAll("\"", "");
                    list += line;
                } else if (line.matches("[ \t]*for[ \t]*.*")) {
                    compoundCommand = "for";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*select[ \t]*.*")) {
                    compoundCommand = "select";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*case[ \t]*.*")) {
                    compoundCommand = "case";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*if[ \t]*.*")) {
                    compoundCommand = "if";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*while[ \t]*.*")) {
                    compoundCommand = "while";
                    count++;
                    list += line;
                } else if (line.matches("[ \t]*until[ \t]*.*")) {
                    compoundCommand = "until";
                    count++;
                    list += line;
                } else if (list.isEmpty()) {
                    commandList.add(line.replaceFirst("[ \t]*&&$", ""));
                }
            } else if (compoundCommand.equals("here")) {
                list += "\n" + line;
                if (line.matches(delimiter)) {
                    compoundCommand = null;
                    commandList.add(list.replaceFirst("[ \t]*&&$", ""));
                    list = "";
                }
            } else if (compoundCommand.equals("for")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("select")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("case")) {
                compound(line, "case", "esac");
            } else if (compoundCommand.equals("if")) {
                compound(line, "if", "fi");
            } else if (compoundCommand.equals("while")) {
                compound(line, "(for|select|while|until)", "done");
            } else if (compoundCommand.equals("until")) {
                compound(line, "(for|select|while|until)", "done");
            }
        }
    }
    return commandList;
}

void compound(String line, String start, String end) {
    list += "\n" + line;
    if (line.matches("[ \t]*" + start + "[ \t]*.*")) {
        count++;
    }
    if (line.matches("[ \t]*" + end + "[ \t]*.*")) {
        count--;
    }
    if (count == 0) {
        compoundCommand = null;
        commandList.add(list.replaceFirst("[ \t]*&&$", ""));
        list = "";
    }
}