With me, cp, and Subprocess

I was a little addicted to the subprocess, so I made a note.

While creating the helper script for deployment, processing equivalent to cp -pr was required. The (incomplete) cp implementation written in Python is as follows.

python_cp


def _copy(src, dst):
    if os.path.isfile(src):
        shutil.copy2(src, dst)
        return
    if os.path.isdir(src) and os.path.isdir(dst):
        target = os.path.join(dst, os.path.basename(src))
        # TODO Fix behavior like cp -pr (If the target directory exists, the files under it/Directory should be preserved)
        if os.path.exists(target):
            shutil.rmtree(target)
        shutil.copytree(src, target)
        return
    if os.path.isdir(src) and os.path.isfile(dst):
        raise IOError(
            "(Src:directory/Dest:file) This combination isn't allowed")

Although there are restrictions (see comments), that case could not occur in this application, so it's OK.

However, as usual, I heard the hallucination that "Wow, the engineer (laughs) who doesn't do it even though I can move cp with Subprocess ..." from the side, so I decided to write an implementation that uses subprocess. ..

subprocess_cp_error


def _copy(src, dst):
    subprocess.Popen(['cp', '-pr', src, dst]).communicate()

However, with this implementation, wildcards cannot be used in src. To interpret the wildcard, you need to pass shell = True to Popen and execute the command through the shell. http://docs.python.jp/2.7/library/subprocess.html#subprocess.Popen

subprocess_cp_error2


def _copy(src, dst):
    subprocess.Popen(['cp', '-pr', src, dst], shell=True).communicate()

So, I thought, "Is this Finish?", But that's not the case. With the above implementation, the cp command doesn't work at all. When shell = True, the command is executed via the shell as described above, but it is equivalent to the following command.

via_shell_error


/bin/sh -c 'cp' '-pr' (src) (dst)

At first glance, it looks good, but in this case -pr is not considered as an option for cp, and src and dst are not considered as arguments for cp. In other words, cp was executed without any arguments, resulting in an error. To be correct, you have to specify it with one character string as follows

via_shell


/bin/sh -c 'cp -pr (src) (dst)'

So, to execute the corresponding subprocess, specify the command given to Popen as a character string instead of an array.

subprocess_cp


def _copy(src, dst):
    subprocess.Popen('cp -pr {0} {1}'.format(src, dst), shell=True).communicate()

Conclusion

Should not be shell = True if not needed w Well, in fact, it also causes shell injection, so the library reference also says, "When using external input, never set it to True!" ...

Recommended Posts

With me, cp, and Subprocess
With me, NER and Flair
With and without WSGI
Programming with Python and Tkinter
Encryption and decryption with Python
Working with tkinter and mouse
Python and hardware-Using RS232C with Python-
Super-resolution with SRGAN and ESRGAN
group_by with sqlalchemy and sum
python with pyenv and venv
py, shebang, venv and me
Works with Python and R
Create and return a CP932 CSV file for Excel with Chalice
Communicate with FX-5204PS with Python and PyUSB
Interactive visualization with ipywidgets and Bokeh
Shining life with Python and OpenCV
Python-Mouse and keyboard operation with pyautogui
Sorting with mixed numbers and letters
Various of Tweepy. Ma ♡ and ♡ me ♡
Robot running with Arduino and python
Install Python 2.7.9 and Python 3.4.x with pip.
Neural network with OpenCV 3 and Python 3
AM modulation and demodulation with python
[Python] font family and font with matplotlib
Scraping with Node, Ruby and Python
Easy Slackbot with Docker and Errbot
Image segmentation with scikit-image and scikit-learn
Authentication process with gRPC and Firebase Authentication
Scraping with Python, Selenium and Chromedriver
Play with Poincare series and SymPy
HTTPS with Django and Let's Encrypt
Photo segmentation and clustering with DBSCAN
Scraping with Python and Beautiful Soup
NAS backup with php and rsync
For me: Infrastructure and network notes
JSON encoding and decoding with python
Path processing with takewhile and dropwhile
Basic authentication and Digest authentication with Flask
Hadoop introduction and MapReduce with Python
[GUI with Python] PyQt5-Drag and drop-
Compare DCGAN and pix2pix with keras
Using Sessions and Reflections with SQLAlchemy
Reading and writing NetCDF with Python
Introduce errBot and work with Slack
Save and retrieve files with Pepper
Async / await with Kivy and tkinter
I played with PyQt5 and Python3
Login with PycURL and receive response
Experimented with unicode, decode and encode
Reading and writing CSV with Python
Multiple integrals with Python and Sympy
Easy parallel execution with python subprocess
Coexistence of Python2 and 3 with CircleCI (1.0)
Easy modeling with Blender and Python
Draw shapes with OpenCV and PIL
Sugoroku game and addition game with python
Upload and download images with falcon
FM modulation and demodulation with Python
Environment construction with pyenv and pyenv-virtualenv