在Windows和Unix中包含$的单引号,双引号和密码

时间:2013-08-14 17:20:01

标签: windows unix escaping cross-platform command-line-arguments

我正在编写一个PHP脚本来自动执行mysqldump命令。我选择的方法是使用exec( $exec_string . ' 2>&1' )。此脚本必须适用于Windows和* nix平台。

可悲的是,有些密码包含可怕的$符号,因此必须引用`-p'passwordcontaining $'。

以下是我到目前为止所提到的挑战:

  • 在* nix上,您必须使用单引号,否则它将扩展 $作为变量。
  • 在Windows上,您必须使用双引号,因为单引号按字面处理
  • 转义$不是一个选项,因为在Windows上反斜杠只会在双引号(\“)之前解释为转义字符,所以\ $将按字面解释
  • 我不知道如何可靠地检测操作系统,以便能够“以交互方式”在单引号和双引号之间切换。

我是否缺少可以跨平台工作的技巧?

3 个答案:

答案 0 :(得分:0)

您可以从 PHP脚本中转储:

 <?php

$dumpSettings = array(
    'include-tables' => array('table1', 'table2'),
    'exclude-tables' => array('table3', 'table4'),
    'compress' => CompressMethod::GZIP, /* CompressMethod::[GZIP, BZIP2, NONE] */
    'no-data' => false,             /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_no-data */
    'add-drop-table' => false,      /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_add-drop-table */
    'single-transaction' => true,   /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_single-transaction */
    'lock-tables' => false,         /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_lock-tables */
    'add-locks' => true,            /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_add-locks */
    'extended-insert' => true       /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_extended-insert */
);

$dump = new MySQLDump('database','database_user','database_pass','localhost', $dumpSettings);
$dump->start('forum_dump.sql.gz');

请参阅https://github.com/clouddueling/mysqldump-php

答案 1 :(得分:0)

对于我最终采用的方法并不感到高兴(MySQLDump类似乎是一种比exec()更强大的方法),但在这里它是为了帮助任何人。

即使我不想进行操作系统检测,乍一看似乎我无法解决引用解释中的问题。令人高兴的是,操作系统检测相对容易,如果您准备做出一些假设,例如“如果它不在Windows上运行,那么它就在某种* nix服务器上”。

这是我的基本方法,我肯定会受到抨击。

// Inside class
protected $os_quote_char = "'"; // Unix default quote character

// Inside constructor
// Detect OS and set quote character appropriately
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
    $this->os_quote_char = '"';

// Method for adding quotes
/**
 * Adds the OS non-interpreted quote character to the string(s), provided each string doesn't already start with said quote character.
 *
 * The quote character is set in the constructor, based on detecting Windows OSes vs. any other (assumed to be *nix).
 * You can pass in an array, in which case you will get an array of quoted strings in return.
 *
 * @param string|array $string_or_array
 * @return string|array
 */
protected function os_quote( $string_or_array ){
    $quoted_strings = array();
    $string_array = (array) $string_or_array;

    foreach ( $string_array as $string_to_quote ){
        // don't quote already quoted strings
        if ( substr( $string_to_quote, 0, 1 ) == $this->os_quote_char )
            $quoted_strings[] = $string_to_quote;
        else
            $quoted_strings[] = $this->os_quote_char . $string_to_quote . $this->os_quote_char;
    }

    if ( is_array( $string_or_array ) )
        return $quoted_strings;
    else
        return $quoted_strings[0];
}

// Actual usage example:
if ( function_exists( 'exec' ) ){
    list( $user, $pwd, $host, $db, $file ) = $this->os_quote( array( DB_USER, DB_PASSWORD, DB_HOST, DB_NAME, $backup_file.'.sql' ) );

    $exec = $this->get_executable_path() . 'mysqldump -u' . $user . ' -p' . $pwd . ' -h' . $host . ' --result-file=' . $file .  ' ' . $db . ' 2>&1';
    exec ( $exec, $output, $return );
}

答案 2 :(得分:-1)

很难猜到,你在说什么限制,但我怀疑其中有些是假的

passthru('mysqldump -uddd -p"pass\'word$" ddd');

在Windows和FreeBSD下为我工作,以及各自shell中的命令本身