[Home]

CLI Stuff

Last Updated - [11/25/2024]

Shy's collection of various cli things or scripts that are super useful!

all preformatted so expect pagebreaks!

FFMPEG Related:

Find all webp's in a folder and create a png from them:

find ./ -name "*.webp" -exec ffmpeg -i {} {}.png \;

This isn't perfect, if you have an "animated" webp then it doesn't generate the png, I use Xconvert usually but this sometimes comes in handy when I am limted to a CLI

put the audio of one video into another:

ffmpeg -an -i video.mp4 -vn -i audio.mp4 -c:a copy -c:v copy output.mov

output must be a "container" format like mov or mkv, and both streams must be compat with that format, in my case I am using aac audio and h265 video

add/replace audio in a video without re-encode:

ffmpeg -i video.mp4 -i audio.mp3 -c copy -map 0:v -map 1:a output.mkv

output must be a "container" format like mov or mkv UNLESS the audio file is something mp4 supports like AAC or mp3

Pixel Perfect 2x Upscale Options:

-vf scale=2*iw:2*ih:flags=neighbor

My NLMeans custom denoise profile:

3:2:5:5

these are my settings for HANDBREAK ffmpeg expects these in a weird order, refer to how handbreak wants the params.

convert a video to prores + aac

ffmpeg.exe -i file.mp4 -map 0:0 -c:v prores -profile:v 0 -c:a none output.mov
ffmpeg -i file.mp4 -vn -map 0:1 -acodec aac -b:a 320k output.aac

refer to my bashrc function that does the same thing, I use ffmpeg.exe in WSL2 since the windows version runs at full speed

my ingest script

#!/bin/bash
cd /mnt/x/VIDEO/INGEST
for f in *.mkv; do ffmpeg.exe -i "$f" -map 0:0 -c:v prores -profile:v 3 -filter:v fps=30 -c:a none "../READYFOREDIT/${f%.*}.mov" && ffmpeg.exe -i "$f" -vn -map 0:1 -acodec copy "../READYFOREDIT/${f%.*}_track1.aac" && ffmpeg.exe -i "$f" -vn -map 0:2 -acodec copy "../READYFOREDIT/${f%.*}_track2.aac"; done

I typically use profile:v 1 and fps=60 but this one is the "HD" ingest. I don't define pix format I let it use defaults which is 422 so thats prefectly fine for youtube (which is 420) as for the profile it controls the bitrate, 0 is 45, 1 is 102, 2 is 147, and 3 is 220mbps. honestly I'd say even 0 (proxy, 45mbps) is fine for what I do, very little quality loss from the original obs recording but i still prefer profile 1. FPS matters, 30fps files will be half the size as 60. I cant give an exact size per hour becuase it actually seems to kind of depend on the content? MAYBE? I can't tell I've ran tests and can't figure it out. Just assume at least 150gb per hour to b safe. However using profile 1 at 30 fps about 4 hours of footage ended up being under 200gb.

script to convert webms to mp4 for editing

#!/bin/bash
cd /mnt/x/VIDEO/INGEST
for f in *.webm; do ffmpeg.exe -i "$f" -crf 26 -preset medium "${f%.*}.mp4"; done

This is for when I need to use a youtube vid or something but the format is in webm, i need to convert it to a reasonable quality mp4 to use it in my videos, this seems to be decent.

script to convert my iphone's 4k videos into 1080p "lossless" h264 for quick editing tasks

#!/bin/bash
cd /mnt/x/VIDEO/INGEST
for f in *.MOV; do ffmpeg.exe -i "$f" -filter:v "scale=iw/2:ih/2" -c:v libx264 -crf 22 -c:a copy "../${f%.*}.mp4"; done;

saves ouput in upper directory.

Convert using nvidia h265 encoder

ffmpeg.exe -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 -i INPUT.mp4 -c:v hevc_nvenc -preset slow OUTPUT.mp4

I get 5.3X speedup for a 1080p 30fps video on my 4070 super, you need extra hw frames for shit like vp9 decode or it breaks, it throws an error on start but still works. Use "264_nvenc" for 264. I use this for encoding REALLY long videos to something I can edit easilly.

ETC:

Find instances of words inside of specific file types:

grep -r --include=*.file "word" .

DO NOT FORGET THE DOT! will search files with ONLY .file extentions and will return each file and each line that "word" is in. For example: grep -r --include=*.vmt "shystudios" . from my materials folder will return stuff like ./shystudios/tools/toolsnodraw_blue.vmt: "$basetexture" "shystudios/tools/nodraw_blue"

Find all text files of a given name and merge them to a single text file:

find . -name 'Archive.txt' -exec cat {} \; > test.txt

I used this to merge all of my ytdlp archive files, which I get when archiving a whole youtube channel into a single master file that the software can check during normal use.

Use the "fuzzy" finder to find files inside a dir:

find . -type f | fzy

install fzy first, look at my bashrc below I just alias this to 'finder'

List all files and folders in the current dir by size:

du -xsh ./* | sort -h

Find all thumbs.db files in current dir tree and delete them:

find . -iname 'thumbs.db' -delete

Find all empty directories in current dir tree and delete them:

find . -type d -empty -delete

Move all files within sub folders into the current top folder:

find . -mindepth 2 -type f -exec mv -f {} . \;

IE: i have a ton of folders with files in them, this moves the files inside of those folders to the folder above, run it from within that folder, DOES NOT DO NAME CONFLICT CHECKS!! this is somewhat better?? than mv */*.* ./ I think? because it shouldn't ???? overwrite?????? MAYBE IDK LOL

Find the drive the current dir is mounted on:

findmnt -T .

dont forget the . very useful for when you are not 100% sure about what drive a folder is on. I use this to ensure my omv /dev-disk-by-uuid's are actaully attached to the disk that I am targeting, usually for backup related stuff.

Download a list of direct links to files:

wget -c -i filename.txt

-c for continue so it doesn't overwrite the file when you drop connection. -i is the list command, newline seperated url list.

Find the actual exec command name for a window manager:

grep "^Exec" /usr/share/xsessions/*

for manually configuring stuff like xinit or gdm or whatever

Find all audio files in a dir recursively and rename them based on their ID3 title:

find . -type f -name '*.ogg' -exec python3 tagrename.py {} \;

You need my script tagrenamer change .ogg to whatever filetype you want

Find LARGER files between two folders and delete them (keep only smaller files):

python3 largerfiles.py /path/to/folder/1 /path/to/folder/1copy >bigger.txt

xargs -d '\n' rm < bigger.txt

You need my script LargerFiles both folders must contain the same exact number of files all with the same files names (go read the github page for more info)

Show the common fingerprint of a pgp key

gpg --show-keys --fingerprint file.pgp

Mount a shared vbox folder from within a linux guest:

sudo mount -t vboxsf NAME_OF_SHARE path_to_mount_point

NAME_OF_SHARE is the actual "name" of the share as defined in virtualbox. I assume you need guest additions for this maybe??? but maybe not.

Windows Specific:

make nvidia control panel actually work if it doesnt just launch:

Get-AppxPackage 'NVIDIACorp.NVIDIAControlPanel' | % { Copy-Item -LiteralPath $_.InstallLocation -Destination $Env:USERPROFILE\Desktop -Recurse -Force; Invoke-Item "$Env:USERPROFILE\Desktop\NVIDIACorp.NVIDIAControlPanel_*\nvcplui.exe" }

this will put a folder in your program files nvidia corp with nvcplui.exe, just run that from then on. U gotta run that command in powershell.

useful stuff for debugging windows wake timers:

powercfg /lastwake [shows events that woke the computer last]
powercfg /waketimers [ shows events that will wake the computer in the near future]
powercfg -devicequery wake_armed [shows what hardware can wake the pc]
[you can selectively disable what can and can't wake via device manager]
powercfg -requests [shows software that would stop your computer from sleeping]

gotta run these in admin cmd, powershell works too

open a WSL shell as root:

wsl -u root

will open the default instance, use -d distroname to specify if you have more than one. You may also need to do wsl --shutdown first if you are having problems with bullshit like usr merge (this is what was happening to me).

Create a virtual box proxy disk for a real physical disk (ie: use a real usb drive or something like that):

VBoxManage.exe createmedium disk --filename "X:\vbox\usbx601.vmdk" --format=VMDK --variant RawDisk --property RawDrive=\\.\PhysicalDrive4

Filename is path where the image will go, it does not have a physical size. rawdrive is a windows specific drive number, refer to the windows disk manager to get the exact disk number. DO NO PUT IN THE WRONG NUMBER!!!

batch file for killing non responding tasks on windows save this as killtasks.bat

@echo off
TITLE Kill Tasks
tasklist.exe /FI "status eq NOT RESPONDING"
echo(
echo Kill These tasks?

CHOICE /M Select /C yn

If Errorlevel 2 goto end
If Errorlevel 1 goto kill

:kill
taskkill.exe /F /FI "status eq NOT RESPONDING"
pause
goto end

:end
exit
HOW TO PUT THIS IN UR RIGHT CLICK:
click the link for the file, put it in the system32 folder
then make a reg entry like:
HKEY_CLASSES_ROOT\DesktopBackground\Shell\taskkilla\Command
and set the default string key there to:
cmd.exe /K killtasks.bat
Then add the following string keys to the taskkilla (or whatever u named it) key:
Icon 		%SystemRoot%\\System32\\imageres.dll,-98
MUIVerb 	Kill not responding tasks
Position 	Bottom

Log out of connected network servers on windows:

net use * /delete
klist purge

can also specify the server in net use

Batch file for swapping between my steam accounts quickly without needing to type the password

@echo off

TITLE Select Steam account

taskkill.exe /F /IM steam.exe

cls
echo(
echo Steam Swap
echo =======================================
echo(
echo 1) "Main"
echo 2) "ShyStudios"
echo 3) "these names can be anything, these are UI only"
echo(

CHOICE /M Select /C 123

If Errorlevel 3 goto 3
If Errorlevel 2 Goto 2
If Errorlevel 1 Goto 1

:3
set username="LOGIN_NAME_3"
goto end
:2
set username="LOGIN_NAME_2"
Goto end
:1
set username="LOGIN_NAME_1"
Goto end

:end

reg add "HKCU\Software\Valve\Steam" /v AutoLoginUser /t REG_SZ /d %username% /f
reg add "HKCU\Software\Valve\Steam" /v RememberPassword /t REG_DWORD /d 1 /f
start steam://open/main

exit

replace the LOGIN_NAME's with the actual username you use to login to your account. If you want more choices add the button you want after /C (like 1234) and more errorlevel if statements with their goto blocks. YOU MUST have the errorlevels listed from highest to lowest, you can also use leters as choices, if your choices are like 1234J6 then J will return errorlevel 5. /cs makes the choice case sensitive

Source Engine Related:

Launch gmod dedi:

./srcds_run -tickrate 33 -game garrysmod +maxplayers 4 +map gm_flatgrass

This is tuned for my lil unlisted test server

run another games's vis on a gmod map:

.\vvis.exe -low -game "C:\STEAM\steamapps\common\GarrysMod\garrysmod\" "c:\map\mapfile"

obviously run this from the bin fodler of your game

run another games's rad on a gmod map:

.\vrad.exe -ldr -final -StaticPropLighting -StaticPropPolys -game "C:\STEAM\steamapps\common\GarrysMod\garrysmod\" "C:\maps\mapname"

generate ssbump:

./height2ssbump.exe -r 100 ./file.tga 17

-r isn't needed but default is 250 the 17 is the bumpscale and really depends on your hightmap. 15-25 is usually good for most things. The heightmap must be in the alpha channel of the tga plz refer to this page for more info

batch file to convert vtf to a tga file, save this as vtf2tga.bat or something:

start "" "T:\STEAM\steamapps\common\GarrysMod\bin\vtf2tga.exe" -i %1%

edit the path to suit your need, drag a vtf file onto the batch file's icon.

Shy's Bashrc stuff:

alias clist='echo newingest tx rmbh ytm yt yta ytanf ytlq yt7 c2prores ffzy ytupdate yt_notitle ytam'
#i use the above to document my commands incase i forget
alias newingest='cd /mnt/x/VIDEO/INGEST'
alias tx='cd /mnt/x/SHARE/TX'
alias rmbh='rm /home/shy/.bash_history'
alias finder='find . -type f | fzy'
alias ytupdate='yt-dlp --cookies /home/shy/.stuff/ytcookies.txt --sponsorblock-remove all --embed-subs --download-archive Archive.txt https://www.youtube.com/playlist?list=MY_DOWNLOAD_PLAYLIST_ID'

function ytm(){
	yt-dlp --no-playlist -f bestaudio --download-archive Archive.txt --cookies "/home/shy/.stuff/ytcookies.txt" $1
}

function yt(){
	yt-dlp --no-playlist --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --sponsorblock-remove all --download-archive Archive.txt $1
}

function ytlq(){
        yt-dlp --no-playlist -S "res:720" --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --sponsorblock-remove all --download-archive Archive.txt $1
}

function yt7(){
        yt-dlp --no-playlist -S "res:1080" --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --sponsorblock-remove all --download-archive Archive.txt $1
}

function yta(){
	yt-dlp --download-archive Archive.txt -S "res:480" --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --no-playlist $1
}

function ytanf(){
	yt-dlp --download-archive Archive.txt --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --no-playlist $1
}

function ytam(){
        yt-dlp --download-archive Archive.txt -f bestaudio --cookies "/home/shy/.stuff/ytcookies.txt" $1
}

function yttw(){
	yt-dlp --download-archive Archive.txt --cookies "/home/shy/.stuff/twitter.com_cookies.txt" $1
}

function c2prores(){
	ffmpeg.exe -i "$1" -map 0:0 -c:v prores -profile:v 0 -c:a none "$1".mov && ffmpeg -i "$1" -vn -map 0:1 -acodec aac -b:a 320k "$1".aac
}

function yt_notitle(){
    yt-dlp --no-playlist --embed-subs --cookies "/home/shy/.stuff/ytcookies.txt" --sponsorblock-remove all --download-archive Archive.txt -o "%(id)s.%(ext)s" $1
}

I've recently changed my yt commands a lil bit because it seems youtube no longer provides the single file formats, im also upping the quality overall. Yt7 is now 1080p ytlq is now 720. yta which is intended for archiving channels and lacks sponsor block is still 480 so I use that for vids i want in really low quality. yt_notitle is mostly for non youtube sites like twitter that will have insane length filenames. ytupdate also is kinda broken, basically youtube will invalidate your cookies every time you use ytdl, so you need to manually fix your cookies, then you can run the command and it will work ONCE each time you fix your cookies. I could fix this probably using the cookies from browser option. I use the windows version of yt-dlp if I need to download age gated vids since it is more up to date compared to the loonix version.