从Ruby / Chef调用时如何转义powershell命令参数?

时间:2015-12-08 18:15:21

标签: ruby powershell chef

我目前遇到了一个标准的Bobby Tables问题,但环境是Chef + Ruby + powershell。

到目前为止,所有solutions I've seen似乎都不合适:它们用引号包围参数,但不完全转义参数。 Shellwordsshellescape看起来很有希望,但它们似乎是特定于bash的。

例如,我可能想在Chef中构建这个windows shell命令:

.\foo.exe BAR="#{node['baz']}"

从SQL开发世界中推广我会天真地期待一个类似这样的接口:

cmd = "foo.exe BAR=?"
args = (node['baz'])
run-command(cmd, args)

run-command将处理转义任何参数的位置。相反,我看到接口让我想起了开发人员必须将SQL构造为字符串并且“手动”转义任何参数时糟糕的旧SQL时间。

有关如何进行的最佳做法的指示?使用system?谢谢!

编辑:要明确,上面的参数baz可以包含任意文本,包括可能的任何字符组合。可以认为它与Bobby Tables问题相同。

1 个答案:

答案 0 :(得分:1)

The easiest generic solution is to use the array form for the int main() { Account Savings; Account Checkings; Account *ptr; Account savings; // Savings account object char choice; // Menu selection // Set numeric output formatting. cout << fixed << showpoint << setprecision(2); do { // Display the menu and get a valid selection. displayMenu(); cin >> choice; while (toupper(choice) < 'A' || toupper(choice) > 'G') { cout << "Please make a choice in the range " << "of A through G:"; cin >> choice; } // Process the user's menu selection. switch(choice) { case 'a': case 'A': cout << "The current balance is $"; cout << savings.getBalance() << endl; break; case 'b': case 'B': cout << "There have been "; cout << savings.getTransactions() << " transactions.\n"; break; case 'c': case 'C': cout << "Interest earned for this period: $"; cout << savings.getInterest() << endl; break; case 'd': case 'D': makeDeposit(savings); break; case 'e': case 'E': withdraw(savings); break; case 'f': case 'F': savings.calcInterest(); cout << "Interest added.\n"; } } while (toupper(choice) != 'G'); return 0; } void displayMenu() { cout << "\n Welcome to The Bank \n"; cout << "-----------------------------------------\n"; cout << "A) Display the account balance\n"; cout << "B) Display the number of transactions\n"; cout << "C) Display interest earned for this period\n"; cout << "D) Make a deposit\n"; cout << "E) Make a withdrawal\n"; cout << "F) Add interest for this period\n"; cout << "G) Exit the program\n\n"; cout << "Enter your choice: "; } void makeDeposit(Account *acct) { double dollars; cout << "Enter the amount of the deposit: "; cin >> dollars; cin.ignore(); acct.makeDeposit(dollars); } void withdraw(Account *acct) { double dollars; cout << "Enter the amount of the withdrawal: "; cin >> dollars; cin.ignore(); if (!acct.withdraw(dollars)) cout << "ERROR: Withdrawal amount too large.\n\n"; } resource's execute property. This avoids all shell parsing an runs the command verbatim.

command

This doesn't work for execute 'whatever' do command ['foo.exe', "BAR=#{node['baz']}"] end style resources though, which take a string for the script chunk to run, including script. There you would need something more tailored to PowerShell and I don't know its rules well enough to say if Shellwords would match.