Use Python and Terminal to Quickly Share Files Locally
This method is platform-agnostic, so it works across macOS, Windows, Linux, etc.
Scenario
You have some files you want to share with someone who’s connected to the same LAN (e.g., Wi-Fi network).
- If you both have Mac, then just use AirDrop.
- If you both have Windows/Linux, use whatever builtin feature they have.
But what if you want to share files, say, from a Mac to a Windows machine?
Python to the Rescue!
Python has a standard library called http.server
which, da, starts an HTTP server! This is darn simple:
1. Get your Local IP Address
You don’t really need to know this for yourself (you can always open your server at localhost:8000
). But if you want to share the address with others, you need the IP. On Linux, you have ip a s
but on Mac you must do:
ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'
2. Start an HTTP Server
Open terminal and type:
python -m http.server
This starts a server at port 8000.
Now open the following address in a browser on the other machine (even your phone):
<your-local-ip-address>:8000
And that’s it! You see your files and directories and you can download them.
Some Important Points
Change the Shared Directory
By default, the server starts at whatever directory you’re currently at in your terminal. If you want to share another directory, first cd
to that. Alternatively, you can use the --directory
(or -d
for short) switch:
python -m http.server --directory <desired-directory>
For example, --directory ~
shares the entire home folder on the HTTP server. Don’t do it!
- The
-m
switch means you don’t have to type the full address of thehttp.server
package, and Python runs whatever there is inside the package’sif __name__ == "main".
- See here for more info about
if __name__ == "main"
. - See here for info about the
-m
switch. - On the other computer, you can download the files using
cURL
orwget
as well.
Fix the “Address Already in Use” Error
If your port 8000 is taken by another program (or by a running http.server
process), you won’t be able to run another instance of it before stopping the previous process. Do this:
sudo lsof -i:8000
It will show something like this:
🍊 sudo lsof -i:8000
Password:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3.1 88405 <user-name> 5u IPv6 0xbfbe761b491ba281 0t0 TCP *:irdmi (LISTEN)
Then stop the process ID (PID) via:
kill $PID
// or
kill -9 $PID //to forcefully kill the port
An alternative approach is to use the -t
switch which directly outputs the PID: sudo lsof -t -i:8000
. Then you can do:
kill -9 `sudo lsof -t -i:8000`
Automate the whole Thing!
You can assign an alias to the previous commands. For example on Mac:
alias ,ser="kill -9 `sudo lsof -t -i:8000` & python -m http.server -d /users/<username>/downloads & open "http://localhost:8000""
If you add this to your shell’s rc file (e.g., zshrc
or bashrc
) then you can just do ,ser
and have your HTTP server up and running while it opens in the default browser. On Other platforms, you probably will have to change open
to something that opens links in the browser.
How to Stop the Server
Just press CTRL-c
in terminal.
What if you want to access the files remotely?
Then you should port-forward 8000
in your router/modem. Alternatively, you can use something like ngrok.