subprocess模块 sys模块
常用模块学习—subprocess模块详解
要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的模块在python2有os.system。
>>> os.system('uname -a')
Darwin Alexs-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun 4 21:43:07 PDT 2017; root:xnu-3248.70.3~1/RELEASE_X86_64 x86_64
0
0是指执行状态,代表执行成功
这条命令的实现原理是什么呢?(视频中讲,解释进程间通信的问题...)
除了os.system可以调用系统命令,,commands,popen2等也可以,比较乱,于是官方推出了subprocess,目地是提供统一的模块来实现对系统命令或脚本的调用。
子流程模块允许您生成新的进程,连接到它们的输入/输出/错误管道,并获得它们的返回码。这个模块打算替换几个较老的模块和功能:os.system os.spawn *
调用子流程的推荐方法是使用run()函数来处理它所能处理的所有用例。对于更高级的用例,底层的Popen接口可以直接使用。
run()函数在python3.5中添加;如果您需要保持与旧版本的兼容性,请参阅较旧的高级API部分。
三种执行命令的方法
subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推荐
subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面实现的内容差不多,另一种写法
subprocess.Popen() #上面各种方法的底层封装
run()方法
用参数运行命令并返回一个完整的流程实例。返回的实例将具有属性args、returncode、stdout和stderr。
默认情况下,stdout和stderr没有被捕获,这些属性将是None。通过stdout=管道和/或stderr=管道来捕获它们。
如果检查是正确的,并且出口代码是非零的,那么它就会产生一个称为processerror。
processerror对象将在returncode属性中拥有退货代码,如果捕捉到这些流,则输出&stderr属性。
如果超时,并且进程花费的时间太长,将会抛出一个超时过期的异常。其他的参数与Popen构造函数是一样的。
标准写法:
subprocess.run(['df','-h'],stderr=subprocess.PIPE,stdout=subprocess.PIPE,check=True)
涉及到管道|的命令需要这样写:
subprocess.run('df -h|grep disk1',shell=True) #shell=True的意思是这条命令直接交给系统去执行,不需要python负责解析
subprocess.run()方法:
[root@wuqianqian-learn ~]# python3
>>> import subprocess
>>> subprocess.run(['df','-h'])
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 2.1G 36G 6% /
devtmpfs 911M 0 911M 0% /dev
tmpfs 920M 0 920M 0% /dev/shm
tmpfs 920M 340K 920M 1% /run
tmpfs 920M 0 920M 0% /sys/fs/cgroup
tmpfs 184M 0 184M 0% /run/user/0
CompletedProcess(args=['df', '-h'], returncode=0) >>> a = subprocess.run(['df','-h'])
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 2.1G 36G 6% /
devtmpfs 911M 0 911M 0% /dev
tmpfs 920M 0 920M 0% /dev/shm
tmpfs 920M 340K 920M 1% /run
tmpfs 920M 0 920M 0% /sys/fs/cgroup
tmpfs 184M 0 184M 0% /run/user/0 >>> a
CompletedProcess(args=['df', '-h'], returncode=0)
>>> a.stdout.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read' >>> a.returncode >>> a.args
['df', '-h'] >>> a.check_returncode() >>> a = subprocess.run(['df','-h'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> a.stdout
b'Filesystem Size Used Avail Use% Mounted on\n/dev/vda1 40G 2.1G 36G 6% /\ndevtmpfs 911M 0 911M 0% /dev\ntmpfs 920M 0 920M 0% /dev/shm\ntmpfs 920M 340K 920M 1% /run\ntmpfs 920M 0 920M 0% /sys/fs/cgroup\ntmpfs 184M 0 184M 0% /run/user/0\n' >>> a.stderr
b'' >>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> a.stdout
b''
>>> a.stderr
b"df: invalid option -- 'f'\nTry 'df --help' for more information.\n" >>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.6/subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['df', '-fdsfh']' returned non-zero exit status 1. >>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
KeyboardInterrupt >>> exit() [root@wuqianqian-learn ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda1 41151808 2199444 36838932 6% /
devtmpfs 932240 0 932240 0% /dev
tmpfs 941748 0 941748 0% /dev/shm
tmpfs 941748 340 941408 1% /run
tmpfs 941748 0 941748 0% /sys/fs/cgroup
tmpfs 188352 0 188352 0% /run/user/0 [root@wuqianqian-learn ~]# df -h |grep vda1
/dev/vda1 40G 2.1G 36G 6% /
[root@wuqianqian-learn ~]#
[root@wuqianqian-learn ~]#
[root@wuqianqian-learn ~]# python3 >>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'subprocess' is not defined >>> import subprocess
>>> a.stdout.read()
KeyboardInterrupt
>>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.6/subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['df', '-h', '|', 'grep', 'vda1']' returned non-zero exit status 1. >>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> a.stderr
b'df: \xe2\x80\x98|\xe2\x80\x99: No such file or directory\ndf: \xe2\x80\x98grep\xe2\x80\x99: No such file or directory\ndf: \xe2\x80\x98vda1\xe2\x80\x99: No such file or directory\n'
>>> a = subprocess.run('df -h |grep vda1',stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
常用模块学习—subprocess模块详解2
subprocess.call()方法
#执行命令,返回命令执行状态 , 0 or 非0
>>> retcode = subprocess.call(["ls", "-l"]) #执行命令,如果命令结果为0,就正常返回,否则抛异常
>>> subprocess.check_call(["ls", "-l"]) #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls') #接收字符串格式命令,并返回结果
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls' #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
>>> res=subprocess.check_output(['ls','-l'])
>>> res
b'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n'[root@wuqianqian-learn ~]# python3 >>> import os
>>> os.system('uname -a ')
Linux wuqianqian-learn 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
>>> import subprocess
>>> subprocess.call(['ls','-lsh'])
total 0
>>> subprocess.check_call(['ls','-lsh'])
total 0
>>> subprocess.check_call(['ls','-lsh'])
total 80K
srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>
4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R
>>> subprocess.getoutput(['ls','-lsh'])
'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R'
>>> subprocess.getoutput(['ls /bin/ls'])
'/bin/ls'
>>> res = subprocess.checkoutput(['ls','-l'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'subprocess' has no attribute 'checkoutput'
>>> res = subprocess.check_output(['ls','-l'])
>>> res
b'total 4\nsrwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n'
>>> help(subprocess.check_output)
Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs)
Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"])
b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally.
To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
b'ls: non_existent_file: No such file or directory\n' There is an additional optional argument, "input", allowing you to
pass a string to the subprocess's stdin. If you use this argument
you may not also use the Popen constructor's "stdin" argument, as
it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"],
... input=b"when in the course of fooman events\n")
b'when in the course of barman events\n' If universal_newlines=True is passed, the "input" argument must be a
string and the return value will be a string rather than bytes.subprocess.Popen()方法常用参数
常用参数
args:shell命令,可以是字符串或者序列类型(如:list,元组)
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
下面这2条语句执行会有什么区别?
a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)
a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
区别是Popen会在发起命令后立刻返回,而不等命令执行结果。这样的好处是什么呢?
如果你调用的命令或脚本 需要执行10分钟,你的主程序不需卡在这里等10分钟,可以继续往下走,干别的事情,每过一会,通过一个什么方法来检测一下命令是否执行完成就好了。
Popen调用后会返回一个对象,可以通过这个对象拿到命令执行结果或状态等,该对象有以下方法
poll()
Check if child process has terminated. Returns returncode
wait()
Wait for child process to terminate. Returns returncode attribute.
terminate()
终止所启动的进程Terminate the process with SIGTERM
kill()
杀死所启动的进程 Kill the process with SIGKILL
communicate()
与启动的进程交互,发送数据到stdin,并从stdout接收输出,然后等待任务结束
a = subprocess.Popen('python3 guess_age.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True) >>> a.communicate(b'') (b'your guess:try bigger\n', b'')
send_signal(signal.xxx)
发送系统信号
pid
拿到所启动进程的进程号
[root@wuqianqian-learn ~]# python3 >>> import os
>>> os.system('uname -a ')
Linux wuqianqian-learn 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:26:13 UTC 2017 x86_64 x86_64 x86_6
>>> import subprocess
>>> subprocess.call(['ls','-lsh'])
total 0
>>> subprocess.check_call(['ls','-lsh'])
total 0
>>> subprocess.check_call(['ls','-lsh'])
total 4.0K
srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>
4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R
>>> subprocess.getoutput(['ls','-lsh'])
'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R'
>>> subprocess.getoutput(['ls /bin/ls'])
'/bin/ls'
>>> res = subprocess.checkoutput(['ls','-l'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'subprocess' has no attribute 'checkoutput'
>>> res = subprocess.check_output(['ls','-l'])
>>> res
b'total 4\nsrwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n'
>>> help(subprocess.check_output)
Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs)
Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"])
b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally.
To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
b'ls: non_existent_file: No such file or directory\n' There is an additional optional argument, "input", allowing you to
pass a string to the subprocess's stdin. If you use this argument
you may not also use the Popen constructor's "stdin" argument, as
it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"],
... input=b"when in the course of fooman events\n")
b'when in the course of barman events\n' If universal_newlines=True is passed, the "input" argument must be a
string and the return value will be a string rather than bytes. >>>
>>> a = subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)
>>> subprocess.Popen()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'args'
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> def sayhi():
... print('run...hahahah')
File "<stdin>", line 2
print('run...hahahah')
^
IndentationError: expected an indented block
>>> def sayhi():
... print('run...hahahah')
... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
File "<stdin>", line 3
a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
^
SyntaxError: invalid syntax
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sayhi' is not defined
>>> def sayhi():
... print('run...hahahah')
... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
File "<stdin>", line 3
a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
^
SyntaxError: invalid syntax
>>> import subprocess
>>> def sayhi():
... print('run...hahahah')
...
>>>
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.stdout
<_io.BufferedReader name=3>
>>> a.stdout.read()
b'run...hahahah\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,cwd="/tmp",stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.stdout.read()
b'run...hahahah\n/tmp\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.stdout.read()
b'run...hahahah\n/root\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.wait()
>>> a = subprocess.Popen('echo $PWD;sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.wait()
>>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE)
>>> a.pid
>>> a.terminate()
>>> a.pid
>>> a.pid
>>> a.pid
>>> a.terminate()
>>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE)
>>> a.pid
>>> a.kill()
>>> a.pid
>>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE)
>>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE)
KeyboardInterrupt
>>> a.pid
>>> a.kill()
KeyboardInterrupt
>>> help(os.kill)
Help on built-in function kill in module posix: kill(pid, signal, /)
Kill a process with a signal.
sys模块参考
http://www.cnblogs.com/aland-1415/p/6613449.html
subprocess模块 sys模块的更多相关文章
- python 常用模块 time random os模块 sys模块 json & pickle shelve模块 xml模块 configparser hashlib subprocess logging re正则
python 常用模块 time random os模块 sys模块 json & pickle shelve模块 xml模块 configparser hashlib subprocess ...
- 4-24日 collections模块 random模块 time模块 sys模块 os模块
1, collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdi ...
- python 全栈开发,Day27(复习, defaultdict,Counter,时间模块,random模块,sys模块)
一.复习 看下面一段代码,假如运行结果有问题,那么就需要在每一步计算时,打印一下结果 b = 1 c = 2 d = 3 a = b+c print(a) e = a + d print(e) 执行输 ...
- shelve模块,sys模块,logging模块
1.shelve模块 用于序列化的模块,shelve模块比pickle模块简单,只有open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型. impor ...
- day13 函数模块之序列化 random 模块 os模块 sys模块 hashlib模块 collections模块
json import json dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串 ...
- Python进阶(九)----json模块, pickle模块, os模块,sys模块,hashlib模块
Python进阶----json模块, pickle模块, os模块,sys模块,hashlib模块 一丶序列化模块 什么是序列化: 将一种数据结构,转换成一个特殊的序列(特殊字符串,用于网络传输 ...
- 常用模块(collections模块,时间模块,random模块,os模块,sys模块,序列化模块,re模块,hashlib模块,configparser模块,logging模块)
认识模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的 ...
- os模块 sys模块 json/pickle 模块 logging模块
目录 模块 1. os模块 2. sys模块 3. json和pickle模块 4. logging模块 (1)日志配置 (2)实际开发中日志的使用 模块 1. os模块 os模块有什么用 与操作系统 ...
- Python模块02/序列化/os模块/sys模块/haslib加密/collections
Python模块02/序列化/os模块/sys模块/haslib加密/collections 内容大纲 1.序列化 2.os模块 3.sys模块 4.haslib加密 5.collections 1. ...
随机推荐
- python实际练习1——简单购物车
要求实现 启动程序后,让用户输入工资,然后打印商品列表 允许用户根据商品编号购买商品 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 可随时退出,退出时,打印已购买商品和余额 自己写的代码是 ...
- mysql数据库操作记录持续更新...
1.查看删除数据库表的唯一约束 SHOW INDEX FROM tbl_name (唯一约束也是索引) ALTER TABLE tbl_name DROP INDEX index_name 2.u ...
- redis持久化方案(十)
方案分为两种方式: 1>Rdb方式 介绍:redis默认的方式,redis通过快照来将数据持久化到磁盘中 a.设置持久化快照的条件 在redis.conf中修改持久化快照的条件,如下: 比如:如 ...
- python学习笔记——(三)文件操作
·集合操作及其相应的操作符表示集合中没有插入,只有添加,因为毕竟无序 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Vergil Zhan ...
- jsonModel使用
流弊的JSON数据模型框架 https://github.com/jsonmodel/jsonmodel 版本 1.3.0 如果你喜欢JSONModel,并且使用了它,请你: star一下 给我一些反 ...
- [配置] win下maven配置
下载解压 打开环境变量 新建MAVEN_HOME 路径为maven根文件夹 PATH 末尾添加 %MAVEN_HOME%\bin; 命令行 mvn -v 检查 添加网易maven镜像库 阿里的也可以 ...
- D1 java概述
首先扯点别的.在学习知识的过程中非常重要的一点是沟通交流,拿自学java来说绝不是抱着一本Head First Java闷头看.感觉自学入门这一阶段相当于启蒙,绝不能向无头苍蝇一样到处乱撞.java的 ...
- python学习6---字典合并
1.针对python3版本 d1={'gao':1,'luo':2} d2={'liu':3,'jia':4} dictMerged1=dict(d1,**d2) print(dictMerged1) ...
- ODS ,EDW,DM
ODS: 操作数据存储ODS(Operational Data Store),操作型数据仓库,最早的数据仓库模型,是数据仓库体系结构中的一个可选部分,ODS具备数据仓库的部分特征和OLTP系统的部分特 ...
- Windows与Linux的命令行命令对比
Windows与Linux的命令行命令对比 * Windows不区分大小写,Linux区分大小写的. sn DOS Command UNIX Equivalent Effect 影响 1 ASSIGN ...