GVKun编程网logo

为什么subprocess.Popen参数长度限制小于操作系统报告的限制?(subprocess.popen stdin)

29

如果您想了解为什么subprocess.Popen参数长度限制小于操作系统报告的限制?的相关知识,那么本文是一篇不可错过的文章,我们将对subprocess.popenstdin进行全面详尽的解释,并

如果您想了解为什么subprocess.Popen参数长度限制小于操作系统报告的限制?的相关知识,那么本文是一篇不可错过的文章,我们将对subprocess.popen stdin进行全面详尽的解释,并且为您提供关于$.getJSON有参数长度限制、Java:如何绕过 Visual Studio 字符串长度限制的字符串长度限制?、python subprocess Popen、python – subprocess.Popen没有正确转义命令行参数?的有价值的信息。

本文目录一览:

为什么subprocess.Popen参数长度限制小于操作系统报告的限制?(subprocess.popen stdin)

为什么subprocess.Popen参数长度限制小于操作系统报告的限制?(subprocess.popen stdin)

我在Linux 3.16.0上运行Python 3.4.3。 我想使用subprocess.Popen来运行一个长单参数(一个复杂的Bash调用),大约200KiB的命令。

根据getconf和xargs ,这应该是在我的范围内:

$ getconf ARG_MAX 2097152 $ xargs --show-limits < /dev/null Your environment variables take up 3364 bytes POSIX upper limit on argument length (this system): 2091740 POSIX smallest allowable upper limit on argument length (all systems): 4096 Maximum length of command we Could actually use: 2088376 Size of command buffer we are actually using: 131072

但是,Python失败的时候会有相当小的限制:

>>> subprocess.Popen('echo %s > /dev/null' % ('a' * (131072-4096)),shell=True,executable='/bin/bash') <subprocess.Popen object at 0x7f4613b58410> >>> subprocess.Popen('echo %s > /dev/null' % ('a' * (262144-4096)),executable='/bin/bash') Traceback (most recent call last): [...] OSError: [Errno 7] Argument list too long

请注意,Python限制与“实际使用”命令缓冲区xargs报告大致相同。 这表明xargs在某种程度上足够聪明,可以从更小的限制开始,根据需要增加它,但是Python不是。

Windows是否返回命令行切换字符?

在bash中输出*的长度限制是多less?

“参数列表太长”限制是否适用于shell buildins?

在cli中指定python模块

c:程序执行问题

问题:

为什么Python限制小于2MiB的操作系统限制?

我可以增加Python限制吗?

如果是这样,怎么样?

无法逃脱Windows的命令shell空间

清除给定的命令行string以匹配文件path

在最后一个参数中的正斜杠导致批文件(“%〜dp0”)目录的path改变

Magnify.exe命令行参数

在Linux和Windows中工作的命令行参数

单个字符串参数的最大大小限制为131072.它与python无关:

~$ /bin/echo "$(printf "%*s" 131071 "a")">/dev/null ~$ /bin/echo "$(printf "%*s" 131072 "a")">/dev/null bash: /bin/echo: Argument list too long

实际上是MAX_ARG_STRLEN决定单个字符串的最大大小:

作为2.6.23以后的附加限制,一个参数不能超过MAX_ARG_STRLEN(131072)。 这可能会变得相关,如果你产生一个长的调用像“sh -c”用长参数生成“”。 (由Xan Lopez和Ralf Wildenhues指出)

请参阅关于ARG_MAX讨论 ,在“参数个数和一个参数的最大长度”下,以及关于unix.stackexchange 这个问题 。

你可以在binfmts.h看到它:

/* * These are the maximum length and maximum number of strings passed to the * execve() system call. MAX_ARG_STRLEN is essentially random but serves to * prevent the kernel from being unduly impacted by misaddressed pointers. * MAX_ARG_STRINGS is chosen to fit in a signed 32-bit integer. */ #define MAX_ARG_STRLEN (PAGE_SIZE * 32) #define MAX_ARG_STRINGS 0x7FFFFFFF ~$ echo $(( $(getconf PAGE_SIZE)*32 )) 131072

您可以传递多个长度为131071字符串:

subprocess.check_call(['echo',"a"*131071,"b"*131071],executable='/bin/bash',stdout=open("/dev/null","w"))

但是一个字符串arg不能超过131071字节。

这个问题与你的类似,但对于Windows。 正如在这种情况下,您可以通过避免shell=True选项来绕过任何shell限制。

否则,您可以像在该场景中那样提供一个到subprocess.Popen()的文件列表,并按照@Aaron Digulla的建议。

$.getJSON有参数长度限制

$.getJSON有参数长度限制

虽然使用起来和post模式一样,其实,根本还是get方法,所以,对于参数还是有长度限制的,

有机会体验了一下,在get图片的base64格式时发现了,果断改为post就行了。

Java:如何绕过 Visual Studio 字符串长度限制的字符串长度限制?

Java:如何绕过 Visual Studio 字符串长度限制的字符串长度限制?

如何解决Java:如何绕过 Visual Studio 字符串长度限制的字符串长度限制??

我正在尝试创建一个简单的程序,用于计算单个字符串中每个字母 A-Z 实例的数量。 示例:
输入:“abc dca”
输出:
有/是 2 个字母 a
有/是 1 个字母 b
有/是 2 个字母 c
有/是 1 个字母 d

class ilikyo
{
public static boolean checkifvalid(String wrds)
{     int stopper  = 0;
    boolean checked = true;
    for(int i = 0; i < wrds.length(); i++)
          {
          if((int)wrds.charat(i) != 32 && (int)wrds.charat(i) < 65)
          {
          System.out.println("error!   " + wrds.charat(i) + "   is not a valid input");
            stopper++;
            checked = false;
          }
        
          }
            if(stopper == 0)
                   {
                   System.out.println("Input is valid!");
                   }
return checked;
}
public static String converttoLower(String wrdy)
{     
String copy = "";
for(int i= 0; i < wrdy.length(); i++)
{
    if((int)wrdy.charat(i) >= 97 || (int)wrdy.charat(i) == 32)
             {
             copy = copy + wrdy.charat(i);
             }
        else
             {
              int Upper = (int)wrdy.charat(i) +32;
                copy = copy + (char)Upper;
             }
}
return copy;
}
public static void sortthealph(String wrd)
          {
          int check  = 0;
          int stopper = 0;
          int spaces = 0;
          wrd = converttoLower(wrd);
          String copy = "";
          for(int i = 97; i <= 122; i++)
                   {
                   int counthowmany = 0;
                  for(int j = 0; j < wrd.length(); j++)
                        {
                        
                               if((int)wrd.charat(j) == i)
                               {
                                     counthowmany++;
                                     check = counthowmany;
                               }
                               if((int)wrd.charat(j) == 32 && stopper == 0)
                               {
                               spaces++;
                            
                               }
                               
                               
                        }
                      if(counthowmany > 0)
                               {
                               System.out.println("there are/is  " + counthowmany + " instance(s) of the letter " + (char)i);
                               }
                        stopper = 1;
                   }
                   System.out.println(copy);
                   System.out.println(" + " + spaces + " spaces");
         
          }
        
public static void main(String[] args)
{

long starttime = System.nanoTime();
String testing = "abc dca";
sortthealph(testing);
long endtime =System.nanoTime();
long totaltime = endtime - starttime;
System.out.println((double)totaltime/1000000000 + "  seconds elapsed");

}


} 

对于像示例中所示的短字符串,这完全可以正常工作,但是当我尝试使用更长的字符串时,我运气不佳
在 jgrasp 编译器上,我收到一个类似如下的错误:

jgraspcoding.java:80: error: constant string too long

在 VS Code 上,字符串超出了边界,因此并不适合屏幕。
所以这基本上就是我的困境,我希望用更大的字符串运行这段代码

解决方法

哈希图将是更简单的方法。通过将字符串转换为字符数组并进行计数。

char[] chars = str.toCharArray();
Map <char,Integer> hash = new HashMap<char,Integer>();


for(char ch: chars) {
    Integer cnt = hash.get(ch);
    hash.put(ch,(cnt == null) ? 1 : cnt +1);
}

for (Map.Entry<char,Integer> entry : hash.entrySet()) {
    System.out.println("there are/is " + entry.getValue() + "  instance(s) of the letter " entry.getKey());
} 

WARN: uncompiled code

python subprocess Popen

python subprocess Popen


subprocess.Popen(args
                ,bufsize=0
                ,executable=None
                ,stdin=None
                ,stdout=None
                ,stderr=None
                ,preexec_fn=None
                ,close_fds=False
                ,shell=False
                ,cwd=None
                ,env=None
                ,universal_newlines=False
                ,startupinfo=None
                ,creationflags=0)
  • 参数args可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数.如果是序列类型,第一个元素通常是可执行文件的路径.我们也可以显式的使用executeable参数来指定可执行文件的路径.在windows操作系统上,Popen通过调用 CreateProcess()来创建子进程,CreateProcess接收一个字符串参数,如果args是序列类型,系统将会通过list2cmdline()函数将序列类型转换为字符串。

  • 参数bufsize:指定缓冲.我到现在还不清楚这个参数的具体含义,望各个大牛指点.

  • 参数executable用于指定可执行程序.一般情况下我们通过args参数来设置所要运行的程序.如果将参数shell设为True,executable将指定程序使用的shell.在windows平台下,默认的shell由COMSPEC环境变量来指定.

  • 参数stdin,stdout,stderr分别表示程序的标准输入、输出、错误句柄.他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承.

  • 参数preexec_fn只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用.

  • 参数Close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管 道.我们不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr).

  • 如果参数shell设为true,程序将通过shell来执行.

  • 参数cwd用于设置子进程的当前目录.

  • 参数env是字典类型,用于指定子进程的环境变量.如果env = None,子进程的环境变量将从父进程中继承.

  • 参数Universal_newlines:不同操作系统下,文本的换行符是不一样的.如:windows下用''\r\n''表示换,而Linux下用''\n''.如果将此参数设置为True,Python统一把这些换行符当作''\n''来处理.

  • 参数startupinfo与createionflags只在windows下用效,它们将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等.

subprocess.PIPE
在创建Popen对象时,subprocess.PIPE可以初始化stdin,stdout或stderr参数.表示与子进程通信的标准流.

subprocess.STDOUT
创建Popen对象时,用于初始化stderr参数,表示将错误通过标准输出流输出.

Popen的方法:
Popen.poll()

用于检查子进程是否已经结束.设置并返回returncode属性.

Popen.wait()
等待子进程结束.设置并返回returncode属性.

Popen.communicate(input=None)
与子进程进行交互.向stdin发送数据,或从stdout和stderr中读取数据.可选参数input指定发送到子进程的参数.Communicate()返回一个元组:(stdoutdata, stderrdata).注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE.同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE.

Popen.send_signal(signal)
向子进程发送信号。

Popen.terminate()
停止(stop)子进程.在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程.

Popen.kill()
杀死子进程.

Popen.stdin
如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令.否则返回None.

Popen.stdout
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令.否则返回None.

Popen.stderr
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令.否则返回None.

Popen.pid
获取子进程的进程ID.

Popen.returncode
获取进程的返回值.如果进程还没有结束,返回None.

python – subprocess.Popen没有正确转义命令行参数?

python – subprocess.Popen没有正确转义命令行参数?

我试图用python调用以下curl命令:

curl -k -F file=@something.zip -F "data={\\"title\\":\\"Another App\\"}" -Lu usr:pwd https://build.phonegap.com/api/v0/apps

为了它的工作,我发现我传入数据的json需要使用反斜杠进行转义.

我可以用…来调用这个命令

os.system(curl -k -F file=@something.zip -F "data={\\"title\\":\\"Another App\\"}" -Lu usr:pwd https://build.phonegap.com/api/v0/apps)

它的工作原理.

但是,当我尝试使用像这样的子进程模块时……

s = 'curl -k -F file=@something.zip -F "data={\\"title\\":\\"Another App\\"}" -Lu usr:pwd https://build.phonegap.com/api/v0/apps'
push = subprocess.Popen(s.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, errors = push.communicate()
print output

…卷曲不起作用,我从api我得到一个错误,我正在使用无效参数,这是我在过去使用不正确的转义json时得到的.

这里发生了什么?为什么我可以用os.system调用这个命令而不是subprocess.Popen?到目前为止,我的假设是分裂正在搞乱字符串中的某些东西,但是当我检查s.split()的输出时,我没有发现任何看起来错误的东西.

解决方法:

也许使用shell = True

push = subprocess.Popen(s, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

今天的关于为什么subprocess.Popen参数长度限制小于操作系统报告的限制?subprocess.popen stdin的分享已经结束,谢谢您的关注,如果想了解更多关于$.getJSON有参数长度限制、Java:如何绕过 Visual Studio 字符串长度限制的字符串长度限制?、python subprocess Popen、python – subprocess.Popen没有正确转义命令行参数?的相关知识,请在本站进行查询。

本文标签: