简体   繁体   English

为什么我不应该使用php的unix命令?

[英]Why shouldn't I use unix commands from php?

Why would you prefer to keep from using bash commands via exec() in php? 你为什么不想在php中通过exec()继续使用bash命令?

I do not consider portability issue (I definitely will not port it to run on Windows). 我不考虑可移植性问题(我肯定不会将其移植到Windows上运行)。 That's just a matter of a good way of writing scripts. 这只是编写脚本的好方法。

On the one hand: 一方面:

  1. I need to write much more lines in php then in bash to accomplish the same task. 我需要在php中编写更多行,然后在bash中完成相同的任务。 For example, when I need to filter some lines in a file, I just can't imaging using something instead of cat file | grep string > new_file 例如,当我需要过滤文件中的某些行时,我无法使用某些内容而不是cat file | grep string > new_file成像 cat file | grep string > new_file . cat file | grep string > new_file This would take much more time and effort to do in php. 这需要花费更多的时间和精力在php中完成。
  2. I do not want to analyze all situations when something might go wrong. 当出现问题时,我不想分析所有情况。 I will just show bash command output to the user, so he would know what exactly happened. 我将向用户显示bash命令输出,因此他会知道究竟发生了什么。
  3. I do not need to write another wrapper around filesystem functions and use it. 我不需要在文件系统函数周围编写另一个包装器并使用它。 It is much more efficient to leverage the OS for file searching, manipulation etc. 利用操作系统进行文件搜索,操作等更有效。

On the other hand: 另一方面:

  1. Calling unix command with exec() might be inefficient in most cases. 在大多数情况下,使用exec()调用unix命令可能效率低下。 It is quite expensive to spawn a separate process. 产生一个单独的过程是非常昂贵的。 Not talking about scripts running under apache, which is even much less efficient than spawning from command line scripts. 不是在谈论在apache下运行的脚本,这甚至比从命令行脚本产生的效率低得多。
  2. Sometimes it turns out to be 'black magic-like' and perl-like scripting. 有时它被证明是“黑魔法般的”和类似perl的脚本。 Though it can be avoided via detailed comments. 虽然可以通过详细的评论来避免。
  3. Maybe I'm just trying to use two different tools together when they are not supposed to. 也许我只是想在他们不应该的时候一起使用两种不同的工具。 Each tool has its own application and should not be mixed together. 每个工具都有自己的应用程序,不应混合在一起。
  4. Even though I'm sure users will not try to run script will malicious purposes, using exec() is a potential security threat. 即使我确定用户不会尝试运行脚本会出现恶意目的,使用exec()是一种潜在的安全威胁。 In most cases user data can be escaped with escapeshellarg() , but it is still an issue to take into account. 在大多数情况下,用户数据可以使用escapeshellarg()进行转义,但这仍然是一个需要考虑的问题。

another reason to avoid this is that it's much easier to create security holes like this. 避免这种情况的另一个原因是,创建这样的安全漏洞要容易得多。 for example, if a user manage to sneak 例如,如果用户设法潜行

`rm -rf /`

(With backticks) into the input, your bash code might actually nuke the server (or nuke something at least). (使用反引号)进入输入,你的bash代码可能实际上是服务器的核心(或者至少是核武器)。

this is mostly a religious thing, most developers try to write code that always works. 这大多是宗教事物,大多数开发人员都试图编写始终有效的代码。 relying on external commands is a sure way to get your code to fail on some systems (even on the same OS). 依赖外部命令是在某些系统上(甚至在相同的操作系统上)使代码失败的可靠方法。

What are you trying to achieve? 你想要实现什么目标? PHP has regex-based functions to find what you need from a file. PHP具有基于正则表达式的函数,可以从文件中查找所需内容。 Yes, you would probably need about 5 lines of code to do it, but it would probably be no more or less efficient. 是的,您可能需要大约5行代码来完成它,但它可能不会更高或更低效。

The main reason against using exec() in PHP is for security. 反对在PHP中使用exec()的主要原因是为了安全。 If you're trusting your user to give you a command to exec() in bash, they could easily run malicious commands, such as installing and starting backdoor trojans, removing files, and the like. 如果您信任您的用户在bash中向您发出exec()命令,他们可以轻松地运行恶意命令,例如安装和启动后门特洛伊木马程序,删除文件等。

As long as you're careful though (use the shell escaping commands to clean user input, restrict the Apache user permissions etc) it shouldn't be a problem. 只要你小心(使用shell转义命令来清理用户输入,限制Apache用户权限等),它应该不是问题。 I'm just working on a complete platform at the moment, which relies on the front-end executing shell processes simply because C++ is much faster than PHP, so I've written a lot of the backend logic as a shell application and keep PHP for the front-end logic. 我现在只是在一个完整的平台上工作,它依赖于前端执行shell进程,因为C ++比PHP快得多,所以我编写了很多后端逻辑作为shell应用程序并保留PHP对于前端逻辑。

Even though you say portability isn't an issue, you never know for certain what the future holds, so I'd encourage you to reconsider that position. 即使你说便携性不是问题,你也永远不知道未来会怎样,所以我鼓励你重新考虑这个立场。 For example, I was once asked to port an editor that was written (by someone else) from Unix to DOS. 例如,我曾被要求将一个由Unix编写的编辑器(由其他人编写)移植到DOS。 The original program wasn't expected to be ported and was written with Unix specific calls deeply embedded in the code. 原始程序预计不会被移植,而是使用深深嵌入代码中的Unix特定调用编写。 After reviewing the amount of work required, we abandoned the task as too time consuming. 在审查了所需的工作量之后,我们放弃了这项任务太费时间。

I have used exec calls in PHP; 我在PHP中使用过exec调用; however, I had no other way to accomplish what I needed (I had to call another program written in another language with no other bridge between the languages). 但是,我没有其他办法可以完成我需要的东西(我不得不称另一种用另一种语言编写的程序,而且语言之间没有其他桥梁)。 However, IMO, exec calls which aren't necessary are ugly. 然而,IMO,exec调用不必要是丑陋的。 As others have said, they can also create security risks and slow your program down. 正如其他人所说,他们也可能产生安全风险并减慢您的计划速度。

As you said yourself, you need to document the exec calls well to be sure they'll be understood by programmers. 正如你自己所说,你需要很好地记录exec调用,以确保程序员能够理解它们。 Why create the extra work? 为什么要创造额外的工作? Not just now but in the future, when any changes to the exec call will also need to be documented. 不仅是现在,而且将来,当需要记录对exec调用的任何更改时。

Finally, I suggest you learn PHP and its functions a bit better. 最后,我建议你学习PHP及其功能更好一点。 I'm not that good with PHP, but in just a matter of minutes with Google and php.net , I think I accomplished the same thing you gave as an example with: 我对PHP不是那么好,但是在谷歌和php.net的短短几分钟内,我想我完成了你给出的一个例子:

$search_results = preg_grep($search_string, file($file_name));
foreach ($search_results as $result) {
    echo $result . "\n";
}

Yes, it's a bit more code, but not that much, and you can put it in a function if appropriate ... and I wouldn't be surprised if a PHP guru could shorten it. 是的,这是更多的代码,但不是那么多,你可以把它放在一个函数中,如果合适的话......如果一个PHP大师可以缩短它,我也不会感到惊讶。

IMHO, the main concern with using exec() to execute *nix commands via PHP is security, more than performance or even code style. 恕我直言,使用exec()通过PHP执行* nix命令的主要问题是安全性,而不仅仅是性能甚至代码风格。

If you have a very good input sanitization (and this is very hard to achieve), you may be able not to have any security hole. 如果你有一个非常好的输入清理(这很难实现),你可能不会有任何安全漏洞。

Personally, if portability isn't an issue, I would totally use *nix commands like grep, locate, etc. anyday over trying to duplicate that functionality in PHP. 就个人而言,如果可移植性不是问题,我会完全使用* nix命令,如grep,locate等,而不是试图在PHP中复制该功能。

It's about using the best tool for the job. 这是关于使用最好的工具来完成工作。 In some cases, arguably more often than most people realize, it is much more efficient to leverage the OS for file searching, manipulation, etc. (amongst other things) 在某些情况下,可以说比大多数人意识到的更频繁,利用操作系统进行文件搜索,操作等等(其中包括)

Lot of people would descend on your like a ton of bricks for even mentioning using exec. 即使提到使用exec,很多人也会喜欢上大量的砖块。 Some people would consider is blasphemy but not me. 有些人会认为是亵渎,但不是我。 I can see nothing wrong with exec for some situations if your server has been properly configured. 如果您的服务器配置正确,我可以看到exec在某些情况下没有任何问题。 The disadvantage though is that you are spawning another process. 但缺点是你正在产生另一个进程。

If you are running your PHP using a web server, the "user" that runs the script may not have permission to run certain shell commands. 如果使用Web服务器运行PHP,则运行该脚本的“用户”可能无权运行某些shell命令。 you said portability is not an issue, but i can guarantee to you that it IS an issue, (unless you are creating PHP scripts for fun). 你说可移植性不是问题,但我可以向你保证这是一个问题,(除非你是为了好玩而创建PHP脚本)。 In the business world where things and condition changes fast, you won't know you might one day have to run your scripts on other platforms. 在事物和条件变化很快的商业世界中,您不会知道有一天您可能需要在其他平台上运行脚本。

php is not a good executor. php不是一个好的执行者。 php spawns a process from apache, and if that process hangs, your apache server will hang, if your site is also running on the same apache; php从apache生成一个进程,如果该进程挂起,如果你的站点也运行在同一个apache上,你的apache服务器将挂起; it will fail. 它会失败。

You can expect to have silly issues like these as well, if it happens you can't even restart apache without killing the spawned process manually from shell. 你可能会遇到像这样的愚蠢问题,如果它发生你甚至无法重启apache而不从shell手动杀死衍生进程。

http://bugs.php.net/bug.php?id=38915 http://bugs.php.net/bug.php?id=38915

therefore, i'm not talking about security, running linux commands from php fails more than you'd think, worst part of using exec, it's not always possible to get error messages back to php. 因此,我不是在谈论安全性,从php运行linux命令失败超过你的想法,使用exec的最糟糕的部分,并不总是可以将错误消息发送回php。 or write subsequent method that depends on what happened with exec. 或编写取决于exec发生的事情的后续方法。

consider this pseudo example: 考虑这个伪示例:

exec ('bash myscript.sh',$x)
if (myScriptWasOk == true) then do this

There is no way that you get that 'myScriptWasOk' variable right. 你没有办法让'myScriptWasOk'变量正确。 You just don't know anything about it, $x will help you sometimes. 你只是对它一无所知,有时候$ x会帮助你。

All this being said, if u need something simple, and if you tested your script and it works ok, just go for it. 所有这些都说,如果你需要一些简单的东西,如果你测试了你的脚本并且它工作正常,那就去吧。

除非您采取极端预防措施以确保执行代码的人员无法使用它,否则它是不安全的。

If you are only aiming for Unix compatibility (which is perfectly fine), I can't see anything wrong with it. 如果你的目标只是兼容Unix(这完全没问题),我看不出它有什么问题。 Virtually server operating system available today is a Unix clone, except of course for Windows which I think is ridiculous to use as a server platform in the first place (and I'm talking from experience here, this is not just Microsoft hatred). 今天几乎可用的服务器操作系统是Unix克隆,当然除了Windows之外我认为首先用作服务器平台是荒谬的(我在这里谈论经验,这不仅仅是微软的仇恨)。 Unix-compatibility is a perfectly legitimate requirement on any server in my opinion. 在我看来,Unix兼容性是任何服务器上完全合法的要求。

The only real reason I can see to avoid it is performance. 我能看到避免它的唯一真正原因是性能。 You will quickly find that executing external processes in general is extremely slow. 您将很快发现执行外部进程通常非常慢。 It's slow in C, and it's slow in PHP. 它在C中很慢,而且在PHP中很慢。 I would think that's the biggest real, non-religious concern. 我认为这是最大的真正的非宗教问题。

EDIT: Oh, and as for the security problem, that's a simple matter of making sure that you are in total control of the variables passed to the operating system. 编辑:哦,至于安全问题,这是一个简单的事情,确保您完全控制传递给操作系统的变量。 It's a concern you have to make when communicating between processes and languages anyway, for example when you do SQL queries. 无论如何,在进程和语言之间进行通信时,您必须要考虑这一点,例如,当您执行SQL查询时。 It's not a big enough reason in my opinion to not do something, it's just something that has to be taken into account in this case, like in every case. 在我看来,这并不足以让我不做某事,这只是在这种情况下必须考虑的事情,就像在每种情况下一样。

If portability really isn't an issue, because you are building a company solution that is always going to be on your own, totally controlled servers, I say go for shell commands as much as you want to. 如果可移植性确实不是问题,因为您正在构建一个始终位于您自己的完全受控服务器上的公司解决方案,我会说您可以根据需要选择shell命令。 There is no inherent security problem as long as you do proper basic sanitation using escapeshellarg() and consorts. 只要您使用escapeshellarg()consorts进行适当的基本卫生设施,就没有固有的安全问题。

At the same time, in my projects portability mostly is an issue, and when it is, I try not to use shell commands at all - only when something can't be done in PHP at all (eg MP3 decoding/encoding, ImageMagick, Video operations) or not reasonably (ie a PHP based solution is way too slow) will I use external commands. 与此同时,在我的项目中,可移植性主要是一个问题,当它出现时,我尝试根本不使用shell命令 - 只有在PHP根本无法完成某些事情时(例如MP3解码/编码,ImageMagick,视频操作)或不合理(即基于PHP的解决方案太慢)我将使用外部命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM