A hands-on walkthrough of the core AWS S3 CLI workflow — from listing buckets to recovering a deleted file — using just four commands you'll actually remember.
Why I Went Back to the CLI for S3
I'll admit it: for a long time, I managed S3 almost entirely through the AWS console. Click into a bucket, drag a file, refresh the page, repeat. It works, but it's slow, and it doesn't scale past a handful of files. At some point I got tired of the clicking and decided to relearn the AWS CLI properly — not the twenty-flag power-user version, just the handful of commands I'd actually use day to day.
What surprised me is how little you need to know to be productive. There are really only a few verbs in play: list, copy, and occasionally delete or sync. Once you internalize the syntax for those, you can move files between your machine and S3 faster than you ever could by clicking through a browser tab. This walkthrough covers exactly that core loop — the same one I use constantly — using a simple scenario: a photo gets deleted locally, and I pull it back down from S3 to prove the round trip actually works.
I'm assuming you already have the AWS CLI installed and configured with credentials that have access to at least one bucket. If you don't, that's a five-minute setup on its own, but it's outside the scope of what I want to cover here. Let's start from a local folder and work outward into the cloud.
Step One: Know What's on Your Machine (and What Isn't)
Before touching S3 at all, it's worth getting comfortable with plain old ls in the folder you're working from. In my case, I had a small local directory with two files: a photo named example.png and a configuration file called photobucket.yaml. Running ls confirmed both were sitting there.
Then, to set up a realistic scenario, I deleted example.png locally — simulating the kind of accidental deletion that happens to everyone eventually. A second ls confirmed only photobucket.yaml remained. This isn't an AWS command at all, obviously, but it's the mental starting point for the rest of the demo: I have a file that no longer exists on my machine, and I know (or at least hope) that a copy still lives in S3. The rest of the walkthrough is about finding it and getting it back.
This is a good moment to point out something that applies to every step from here on: whenever you're working with cloud storage, it's worth having a habit of checking your local state before and after each command. It sounds trivial, but it's the fastest way to catch mistakes — wrong destination path, wrong bucket, overwritten file — before they become a real problem.
Step Two: Listing Your Buckets
With the local file gone, the next question is: which bucket has my backup? If you already know the bucket name, you can skip this step entirely. But if you're working across multiple projects or accounts, it's useful to just ask AWS what's available.
The command is about as simple as CLI commands get:
aws s3 ls
Run without any arguments, this lists every bucket your credentials have access to, along with creation timestamps. It's essentially the S3 equivalent of ls at the root level — a quick sanity check on what exists before you drill into anything specific.
One practical note here: bucket names in S3 are globally unique across all of AWS, not just within your account, which is why you'll often see people using fairly specific or personalized naming conventions to avoid collisions. If you're setting up your own buckets, it's worth thinking for a second about whether the name you choose is something you'd be comfortable having visible in a screen recording, a terminal history, or a shared script — bucket names have a way of ending up on screen more often than you'd expect. For this walkthrough, I'll just refer to the bucket as my-photos-bucket, but obviously substitute your own.
Step Three: Drilling Into a Bucket and Prefix
Once I knew which bucket held my photos, the next step was narrowing down to the right file. S3 doesn't have real folders — what looks like a folder structure is actually just a naming convention using prefixes — but the CLI lets you treat it like a directory tree anyway, which keeps things intuitive.
The command looks like this:
aws s3 ls s3://my-photos-bucket/photos
That lists everything under the "photos" prefix inside the bucket, the same way ls would list a subdirectory locally. Sure enough, example.png showed up in the output, confirming a copy existed in S3 even though it was gone from my local machine.
This two-step pattern — list buckets, then list a specific bucket or prefix — is worth internalizing because it's the same shape you'll use constantly, whether you're hunting for a specific file, checking whether a backup job actually ran, or just poking around to understand how a bucket is organized. It's slower than remembering exact paths by heart, but it's a lot faster than opening the console and clicking through folder after folder.
Step Four: Downloading the File Back
With the file located, the last step was pulling it back down to my local machine using aws s3 cp. This is the command that trips people up most often, mainly because of argument order, so it's worth being explicit about it.
The syntax is:
aws s3 cp <source> <destination>
Source comes first, destination comes second — same as the Unix cp command it's modeled after. To download, the source is the S3 path and the destination is a local path:
aws s3 cp s3://my-photos-bucket/photos/example.png .
That trailing . means "the current folder," which is the simplest destination you can specify — it tells the CLI to save the file with its original name right where you're standing. You could also give it a full local path or rename the file on the way down by specifying a different filename as the destination.
After running the command, a final ls in the local folder confirmed example.png was back, sitting alongside photobucket.yaml exactly as it had been before the deletion. That's the whole round trip: gone locally, still safe in S3, recovered with a single copy command. It's a small example, but it's the same mechanic you'd use to restore a config file, pull down a build artifact, or sync assets onto a new machine.
The Pattern Worth Remembering
Strip away the specific file names and what you're left with is a four-command loop: list buckets to orient yourself, list a bucket or prefix to locate a file, copy to move it in either direction, and — though I didn't need it here — delete when you actually want something gone from S3 for good (aws s3 rm). Almost everything else in the S3 CLI is a variation or extension of this same handful of ideas: sync for keeping whole directories mirrored, extra flags for permissions or storage classes, and so on. But you don't need any of that to be productive.
If you're coming from the console, the biggest adjustment is trusting the terminal output instead of a visual file browser. It takes a session or two to stop double-checking everything in the AWS web console, but once it clicks, it's genuinely faster — especially for anything repetitive, like pulling down the same file across multiple environments or checking a bucket's contents as part of a script.
A quick word of caution, since it applies to CLI work with any cloud provider: if you're ever recording your screen or sharing a terminal session while doing this kind of work, keep an eye on what's actually visible — bucket names, file paths, and account details all show up in plain text in your command history and output. It's easy to reveal more than you intended without realizing it in the moment.
Conclusion
If you've got five minutes and a test bucket you don't mind experimenting with, try this exact sequence yourself: list your buckets, drill into one, copy a file down, and then copy it back up with aws s3 cp in reverse. Doing it once with your own hands will cement the argument order and prefix syntax far better than reading about it ever will.
Official AWS references
KEEP PRACTICING THE DECISION
Learn the concept, then test the edge case.
The Solutions Architect Associate course in TutorialRepo combines guided lessons, scenario questions, review, and course-aware explanations.