Argument list too long错误

本文介绍了在删除大量文件时遇到的Argumentlisttoolong错误及其解决办法。通过使用find命令结合exec选项或ls配合xargs命令来绕过shell参数长度限制,实现高效批量删除。

原贴:http://www.zhangjianfeng.com/?p=358

Argument list too long错误

删除文件时,报"-bash: /bin/rm: Argument list too long"错误.查了一下,
[root@srv1 mqueue]# ls -l |wc -l
 319913
应该是文件数量太大了吧,记得应该是shell的限制,rm mv cp都受此限制。
解决方法:find所有文件,然后送给rm删除.
find /var/spool/mqueue -type f -exec rm {} /;

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/cpa/ads?client=ca-pub-9932809095109167&cpa_choice=CAEaCG25ta-KCIutUBJQBVAtUAdQQ1AvUEdQAw&oe=utf-8&dt=1190277355781&lmt=1190277355&format=468x60_as&output=html&correlator=1190277355765&channel=9299699904&url=http%3A%2F%2Fwww.zhangjianfeng.com%2F%3Fp%3D358&region=_google_cpa_region_&ref=http%3A%2F%2Fwww.google.cn%2Fsearch%3Fcomplete%3D1%26hl%3Dzh-CN%26ie%3DGB2312%26q%3Dlinux%2Brm%2Bargument%2Btoo%2Blong%26btnG%3DGoogle%2B%25CB%25D1%25CB%25F7%26meta%3D%26aq%3Dnull&cc=100&ga_vid=636176395.1190277356&ga_sid=1190277356&ga_hid=2072357979&flash=9&u_h=1024&u_w=1280&u_ah=904&u_aw=1280&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="468" scrolling="no" height="60" allowtransparency="allowtransparency">
##最后修改日期, Thursday, October 12th, 2006 2:30 pm##  

 

2007年09月

以root身份进入/var/spool/clientmqueue/
执行:
ls|xargs rm -f 就能全部删除了
这样效率比较高

<think>我们正在处理一个Linux环境下执行Python脚本调用SQL脚本时出现的“argument list too long错误。这个错误通常发生在命令行参数过长时,Linux系统对命令行参数的长度有限制。 根据引用[1]的内容,我们有一个脚本示例,其中使用了Python和数据库操作。虽然引用[1]没有直接展示调用SQL脚本,但我们可以借鉴其处理方式。 错误原因: 在Linux中,当执行一个命令时,传递给命令的参数(包括环境变量)的总大小超过了系统限制(通常由`ARG_MAX`决定),就会引发“argument list too long错误。在调用SQL脚本时,如果SQL脚本非常大或者包含大量的参数,就可能出现这个问题。 解决方案: 1. 检查并优化参数:减少传递给命令的参数数量或长度。 2. 使用文件传递参数:将参数写入文件,然后通过文件读取参数,而不是直接通过命令行传递。 3. 使用管道或重定向:将数据通过管道传递给命令,而不是作为参数传递。 4. 调整系统参数:增大`ARG_MAX`限制,但这需要系统权限,且不推荐,因为可能影响系统稳定性。 具体到我们的场景:Python脚本调用SQL脚本。假设我们使用类似以下的方式调用: subprocess.call(['sqlite3', 'database.db', '<', 'large_script.sql']) 或者 subprocess.call(['mysql', '-u', 'user', '-p', 'dbname', '<', 'large_script.sql']) 但是,如果SQL脚本文件非常大,或者我们在命令行中传递了大量的参数(比如大量的INSERT语句作为参数),就会导致问题。 我们可以考虑以下方法: 方法1:使用重定向(输入重定向)来传递SQL脚本文件 在命令行中,我们通常用`<`将文件重定向到命令的标准输入。但是注意,在subprocess模块中,我们不能直接使用shell的重定向符号,除非设置`shell=True`(不推荐,因为安全风险)。我们可以使用以下方式: ```python with open('large_script.sql', 'r') as sql_file: subprocess.call(['mysql', '-u', 'user', '-p', 'dbname'], stdin=sql_file) ``` 这样,SQL脚本通过文件句柄传递给子进程的标准输入,避免了命令行参数过长。 方法2:将SQL命令拆分成多个小文件,分批执行。 方法3:如果是因为SQL脚本本身过大,考虑优化SQL脚本,比如使用LOAD DATA INFILE(在MySQL中)代替大量的INSERT语句。 方法4:使用其他方式传递数据,例如如果数据是从Python生成,可以考虑使用管道将数据传递给数据库命令行工具,逐行处理或批量处理。 示例代码(使用Python生成数据并导入到MySQL,避免一次性传递大量数据): 如果数据是由Python生成的,我们可以边生成边通过管道传递给mysql命令: ```python import subprocess # 启动mysql进程,并打开管道到其标准输入 mysql_process = subprocess.Popen(['mysql', '-u', 'user', '-p', 'dbname'], stdin=subprocess.PIPE) # 生成SQL语句并写入管道 for i in range(large_number): # 生成一条SQL语句,注意要符合MySQL的语法 sql_line = f"INSERT INTO table VALUES ({i}, 'data');\n" mysql_process.stdin.write(sql_line.encode()) # 关闭管道,等待完成 mysql_process.stdin.close() mysql_process.wait() ``` 但注意,这种方法如果数据量极大,可能会占用较多内存,建议分批次写入(比如每1000条提交一次)。 另外,如果使用SQLite,也有类似的批量操作方式。 方法5:使用数据库API的批量操作功能,而不是通过命令行工具。例如,使用Python的MySQLdb或sqlite3模块,直接连接数据库,然后执行SQL语句,这样就不会有命令行参数限制的问题。 例如,使用sqlite3模块: ```python import sqlite3 conn = sqlite3.connect('database.db') cursor = conn.cursor() with open('large_script.sql', 'r') as f: # 注意:如果文件很大,可以分块读取执行,或者使用executescript(如果脚本包含多条语句) cursor.executescript(f.read()) conn.commit() ``` 或者逐行执行: ```python with open('large_script.sql', 'r') as f: for line in f: # 忽略空行和注释 if line.strip() and not line.strip().startswith('--'): cursor.execute(line) conn.commit() ``` 使用这种方法,我们完全避开了命令行参数长度的限制。 总结:推荐使用数据库API直接操作数据库(方法5)或者使用标准输入重定向(方法1)来避免“argument list too long错误。 注意:如果使用标准输入重定向,确保SQL脚本文件不会过大导致内存不足。如果文件非常大,建议使用数据库API并分块处理。 相关问题: 1. 如何查看Linux系统的ARG_MAX限制? 2. 在Python中,使用subprocess模块时,如何安全地传递大量数据给子进程? 3. 使用Python的数据库API(如sqlite3)执行大型SQL脚本时,如何优化内存使用?</think>### Linux执行Python脚本调用SQL脚本时出现"argument list too long"错误的解决方案 当在Linux系统中执行Python脚本调用SQL脚本时出现"argument list too long"错误,这通常是由于命令行参数或环境变量总大小超过系统限制造成的。Linux内核默认限制为$2MB$(可通过`getconf ARG_MAX`查看)。以下是逐步解决方案: #### 1. **使用输入重定向替代命令行参数**(推荐) 将SQL脚本内容通过标准输入传递,避免作为命令行参数: ```python import subprocess # 原始问题代码(可能导致错误) # subprocess.call(["mysql", "-u", "user", "-p", "dbname", "<", "large.sql"]) # 修正方案:使用文件句柄重定向 with open("large.sql", "r") as sql_file: subprocess.call( ["mysql", "-u", "user", "-p", "dbname"], stdin=sql_file # 通过标准输入传递SQL内容 ) ``` #### 2. **分批执行SQL语句** 对于巨型SQL文件,分割后分批执行: ```python import sqlite3 CHUNK_SIZE = 1000 # 每批执行的语句数 conn = sqlite3.connect("database.db") cursor = conn.cursor() with open("large.sql") as f: statements = [] for line in f: if line.strip().endswith(";"): statements.append(line) if len(statements) >= CHUNK_SIZE: cursor.execute("".join(statements)) statements = [] if statements: cursor.execute("".join(statements)) conn.commit() ``` #### 3. **使用数据库API直接执行** 完全避免命令行调用,改用Python数据库接口: ```python import MySQLdb # 或 import sqlite3 conn = MySQLdb.connect(host="localhost", user="user", password="pass", db="dbname") with open("large.sql") as f: sql = f.read() # 自动分批执行 for statement in sql.split(";"): if statement.strip(): conn.cursor().execute(statement) conn.commit() ``` #### 4. **临时提高系统限制(需root权限)** 临时调整内核参数(重启后失效): ```bash # 查看当前限制 $ getconf ARG_MAX # 临时提高限制(例如设为4MB) $ sudo sysctl -w kernel.arg_max=4194304 ``` #### 5. **优化SQL脚本结构** 减少SQL语句冗余: - 用`INSERT INTO ... VALUES (...), (...), ...`代替多个单行INSERT - 使用`LOAD DATA INFILE`(MySQL)或`.import`(SQLite)直接导入CSV - 删除不必要的空格和注释 > **关键原因**:当Python通过`subprocess`调用外部命令时,整个命令(包括参数和环境变量)必须符合Linux内核的`ARG_MAX`限制。直接使用数据库API可彻底规避此限制[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值