DEV Community

Cover image for Creating files with Python and mimicking the "touch command"
Gagan Deep Singh
Gagan Deep Singh

Posted on

Creating files with Python and mimicking the "touch command"

We will learn the following while working on our Python Script:

  1. Creating files with Python

  2. Touch command

  3. Result

Creating files with Python

Creating a single file

Here's a one-liner for creating a file with Python.



open('hello_world.txt','w')


Enter fullscreen mode Exit fullscreen mode

This single statement creates hello_world.txt, but we don't want fixed file names, do we?

The question is, how to conveniently provide input to the script to create a file with Python.

We can use a variable for storing the name of the file, like this...



filename = "hello_world.txt"
open(filename, 'w')


Enter fullscreen mode Exit fullscreen mode

But this will be a mess if we want to create multiple files with Python, as each time we want to create a file, we would need to update filename variable manually which ain't so cool.

Creating multiple files

The solution to the above problem is, making a list of filenames.



filenames = ['hello_world.txt', 'random_file.txt', 'lol.txt']
for filename in filenames:
    open(filename, 'w')


Enter fullscreen mode Exit fullscreen mode

This is MUCH BETTER 🀩! But wait, It's only good for one-time use πŸ˜•. What if we want to make more files later in a single go?

Then we would have to update the filenames list again and again. πŸ˜‘

Providing filenames from the command line

For this fix, we can provide values (filenames) from the command line! πŸ˜ƒ We only need to make two changes in our existing code.

Add from sys import argv and use the value of argv with for filenames.



from sys import argv

filenames = argv[1:] # Ignore the first element (script file)

for filename in filenames:
    open(filename, 'w')


Enter fullscreen mode Exit fullscreen mode

This seems to work just fine but there's a nasty bug in it.

If the file already exists, it will wipe the whole file's contents. Thanks to the file access mode 'w' (write mode) which we used.

The fix is very simple. We just need to replace 'w' with 'a' (append mode) which will ignore the files which already exist and create new ones if they don't.



from sys import argv

filenames = argv[1:] # Ignore the first element (script file)

for filename in filenames:
    open(filename, 'a') # Using append mode now


Enter fullscreen mode Exit fullscreen mode

Testing our script

I saved the script as touch.py here's the execution...

creating files in terminal

Creating multiple files with our Python script

checking if file remains intact

Existing files remain unchanged, YAY!

Touch command

Our script is GOOOOOODDD!!! πŸ”₯πŸ”₯πŸ”₯

But there's still one thing we can add to make it behave more like touch command, that is, updating a file's access and modified time.

For the sake of keeping things simple, we will just update the modified time of the file.

Getting the access time and modified time of a file

The os module in Python has a stat function that performs a stat system call (runs a stat command behind the scenes) and returns the result in an accessible way.



from os import stat
st_info = stat(filename)

access_time = st_info.st_atime 
modified_time = st_info.st_mtime


Enter fullscreen mode Exit fullscreen mode

We can use the result st_info which contains the status of the file including the access and modified time for modifying the file.

Getting the current time

time function in the time module returns the current time which we can directly use in our script for modifying the files with our script.



from time import time
current_time = time() # current time in seconds (since Epoch)

Enter fullscreen mode Exit fullscreen mode




Updating Access and Modified time in a file

The os module also has a function for updating this access and modified time called utime.

Here's how this can be done,



from os import utime

# if the second argument isn't passed, it will set the access

and modified time to current time


utime(filename)

# for setting our custom access and modified time
utime(filename, (access_time, current_time))

Enter fullscreen mode Exit fullscreen mode




Implementing the Touch Command

Now, we can finally put together everything we have done so far in one final script.



from sys import argv
from time import time
from os import utime, stat

for name in argv[1:]:
open(name, 'a')
st_info = stat(name) # Storing file status
# setting access time with file's access time (no change)
# setting modified time with current time of the system)
utime(name, (st_info.st_atime, time()))

Enter fullscreen mode Exit fullscreen mode




Result

Finally, It's time we use the script for creating files and stuff.

Creating multiple files

Multiple files created Succesfully! πŸ”₯

giving existing file to our script

Our script successfully updates the modified time of existing file!! πŸ”₯

That's it! Our script makes multiple files and mimics the touch command as it sets the modified time! πŸŽ‰πŸŽ‰πŸŽ‰

You can tweak it and add more features to make it a complete touch command clone.

Link to script file

Top comments (3)

Collapse
 
ashwinsharmap profile image
Ashwin Sharma P

Good article Gagan. Liked itπŸ‘

Collapse
 
bhargav_25 profile image
Bhargav Gohil

How do I enable this script in all folders in that directory. Like I want to use this command in different folder, so how do I use this globally ?

Collapse
 
bhargav_25 profile image
Bhargav Gohil

So, yeah I found out the way to run this script from anywhere.
1) First you have to add this line on the top of script #!/usr/bin/env python3
2) Then you have to run this $ chmod +x touch.py , this will allow you to run the script Globally.
3) You need to add a PATH to ./bashrc this add this line export PATH="$PATH:/home/<system name>/<folder in which script is present>

4) Now you have to remove the extension i.e make touch.py to touch
5) Now, go to the folder /home/<system name>/<folder in which script is present>
6) Now, you can run this script from anywhere, just by writing touch.

7) Coool!