# Share your shell/bash/bat scripts

**URL:** https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017
**Category:** General
**Tags:** Scripts
**Created:** [August 6, 2025, 1:42pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017 "2025-08-06T13:42:31Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![ars18](https://jtechforums.org/user_avatar/jtechforums.org/ars18/32/11805_2.png) [@ars18](https://jtechforums.org/u/ars18)
#### Post date: [January 5, 2026, 5:00am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/26 "2026-01-05T05:00:23Z")

</div>

> [@jumptoheaven](#):
>
> Not everyone is a Linux junkie.

I’m trying to get help I promise

---

<div class="post-metadata">

### Author: ![DaWelch](https://jtechforums.org/user_avatar/jtechforums.org/dawelch/32/5235_2.png) [@DaWelch](https://jtechforums.org/u/DaWelch)
#### Post date: [January 5, 2026, 6:39pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/27 "2026-01-05T18:39:32Z")

</div>

> [@jumptoheaven](#):
>
> Not everyone is a Linux junkie.

Hey! I also have TWO Windows laptops!

---

<div class="post-metadata">

### Author: ![TripleU](https://jtechforums.org/user_avatar/jtechforums.org/tripleu/32/488_2.png) [@TripleU](https://jtechforums.org/u/TripleU)
#### Post date: [January 6, 2026, 12:30am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/28 "2026-01-06T00:30:15Z")

</div>

> [@jumptoheaven](#):
>
> Not everyone is a Linux junkie.

 ![image](https://jtechforums.org/uploads/default/original/2X/a/a626cef4d3a669442ba12fbd8459b59095641ed2.jpeg)

---

<div class="post-metadata">

### Author: ![Dev-in-the-BM\_2.0](https://jtechforums.org/user_avatar/jtechforums.org/dev-in-the-bm_2.0/32/969_2.png) [@Dev-in-the-BM\_2.0](https://jtechforums.org/u/Dev-in-the-BM_2.0)
#### Post date: [January 6, 2026, 1:03am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/30 "2026-01-06T01:03:22Z")

</div>

The more Windows PC’s you have, the bigger the chance that you have a Linux machine.

---

<div class="post-metadata">

### Author: ![anon24812444](https://jtechforums.org/letter_avatar_proxy/v4/letter/a/e495f1/32.png) [@anon24812444](https://jtechforums.org/u/anon24812444)
#### Post date: [January 13, 2026, 11:26pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/31 "2026-01-13T23:26:53Z")

</div>

### script to set all artist tags to based on its folder name
  
  

#### how it works

```auto
VAST_AUDIO_LIBRARY/ ← Run script HERE (current directory)
│
├── folder_to_artist_tag.sh ← The script file (place here)
│
├── 8th day/ ← FOLDER = Artist name "8th day"
│ ├── We All Belong.mp3 ← Check: artist tag = "8th day"? 
│ ├── All You Got/ ← Subfolder (script searches recursively)
│ │ ├── 01 - Mazal Tov.mp3 ← Check: artist tag = "8th day"?
│ │ ├── 02 - Bounce.mp3 ← If tag = "8th Day" → UPDATE to "8th day"
│ │ └── 03 - Harmony.mp3 ← If tag = "8th day" → SKIP (already correct)
│ └── Brooklyn/
│ ├── 01 - Brooklyn.mp3
│ └── 02 - Don't Say Goodbye.mp3
│
├── Avraham Fried/ ← FOLDER = Artist name "Avraham Fried"
│ ├── song1.mp3 ← Check: artist tag = "Avraham Fried"?
│ ├── song2.mp3 ← If wrong → UPDATE to "Avraham Fried"
│ └── Album Name/
│ └── track.mp3 ← Also checked (recursive search)
│
├── Mordechai Ben David/ ← FOLDER = Artist name "Mordechai Ben David"
│ ├── track1.mp3 ← All files here get artist = "Mordechai Ben David"
│ └── track2.mp3
│
└── Yaakov Shwekey/ ← Each top-level folder = one artist
    └── songs/
        └── song.mp3

HOW IT WORKS:
═════════════

1. START in VAST_AUDIO_LIBRARY/
   │
   ├─→ Find all folders (8th day/, Avraham Fried/, etc.)
   │
   └─→ For EACH folder:
       │
       ├─→ Folder name = Expected Artist Name
       │
       ├─→ Find ALL audio files inside (recursively)
       │ (searches subfolders too)
       │
       └─→ For EACH audio file:
           │
           ├─→ Read current artist tag
           │
           ├─→ Does it match folder name?
           │ │
           │ ├─→ YES: Skip (already correct)
           │ │
           │ └─→ NO: Update tag to match folder name
           │
           └─→ Move to next file

EXECUTION:
══════════

Terminal view:
┌─────────────────────────────────────────────────────────┐
│ ploiny@computer:/media/VAST_AUDIO_LIBRARY$ │
│ │
│ $ bash folder_to_artist_tag.sh │
│ │
│ [CHECK] Looking for tools... │
│ [OK] eyeD3 found! │
│ [INFO] Using tool: eyeD3 │
│ │
│ [FOLDER 1/294] Processing: '8th day' │
│ [FILE 1/104] Checking: 8th day/song.mp3 │
│ Current: '8th Day' → Updating to '8th day' │
│ [SUCCESS] Updated! │
│ │
│ [FILE 2/104] Checking: 8th day/song2.mp3 │
│ Current: '8th day' → Already correct, skipping │
│ │
│ [FOLDER 2/294] Processing: 'Avraham Fried' │
│ ... │
└─────────────────────────────────────────────────────────┘

IMPORTANT RULES:
════════════════

✓ One artist = One top-level folder
✓ Folder name becomes the artist tag for ALL files inside
✓ Subfolders are OK (albums, etc.) - script searches recursively
✓ Files already matching = skipped (no unnecessary rewrites)
✓ Script must have WRITE permission to the files
✓ Works on: MP3, M4A, FLAC, OGG, WAV

EXAMPLE CORRECTION:
═══════════════════

BEFORE running script:
  Folder: "8th day"
  File: "8th day/song.mp3" has tag: artist="8th Day"
                                            ↑
                                     (capital D)

AFTER running script:
  Folder: "8th day"
  File: "8th day/song.mp3" has tag: artist="8th day"
                                            ↑
                                     (lowercase d - matches folder!)

```

#### basically if you want to browse your organized artists in music players the same way you do in file managers (like me) this should be helpful

#### execute doing “bash path/to/sript.sh” not “./script”
  
  

## very important: proper placement of script is crucial!!

> **Script**
>
> ```auto
> #!/bin/bash
> 
> echo "=========================================="
> echo "Artist Tag Fixer - Starting"
> echo "=========================================="
> echo ""
> 
> # Check for available tools (prioritized by reliability and speed)
> echo "[CHECK] Scanning for available audio tagging tools..."
> echo ""
> 
> TOOL=""
> TOOL_NAME=""
> 
> # Priority 1: eyeD3 - best for MP3, modifies in-place, works well on FAT32
> echo "[CHECK] Looking for eyeD3..."
> if command -v eyeD3 &> /dev/null; then
> echo "[OK] eyeD3 found!"
> TOOL="eyeD3"
> TOOL_NAME="eyeD3"
> fi
> 
> # Priority 2: mid3v2 - also good for MP3, modifies in-place
> if [-z "$TOOL"]; then
> echo "[CHECK] Looking for mid3v2..."
> if command -v mid3v2 &> /dev/null; then
> echo "[OK] mid3v2 found!"
> TOOL="mid3v2"
> TOOL_NAME="mid3v2"
> fi
> fi
> 
> # Priority 3: kid3-cli - versatile, handles many formats
> if [-z "$TOOL"]; then
> echo "[CHECK] Looking for kid3-cli..."
> if command -v kid3-cli &> /dev/null; then
> echo "[OK] kid3-cli found!"
> TOOL="kid3-cli"
> TOOL_NAME="kid3-cli"
> fi
> fi
> 
> # Priority 4: exiftool - works but slower
> if [-z "$TOOL"]; then
> echo "[CHECK] Looking for exiftool..."
> if command -v exiftool &> /dev/null; then
> echo "[OK] exiftool found!"
> TOOL="exiftool"
> TOOL_NAME="exiftool"
> fi
> fi
> 
> # Priority 5: ffmpeg - requires write permissions, creates temp files
> if [-z "$TOOL"]; then
> echo "[CHECK] Looking for ffmpeg..."
> if command -v ffmpeg &> /dev/null; then
> echo "[OK] ffmpeg found!"
> TOOL="ffmpeg"
> TOOL_NAME="ffmpeg"
> fi
> fi
> 
> # If no tool found, exit
> if [-z "$TOOL"]; then
> echo ""
> echo "[ERROR] No supported audio tagging tools found!"
> echo "[INFO] Please install one of the following (in order of preference):"
> echo " 1. eyeD3: sudo apt install eyed3 (RECOMMENDED for FAT32/vfat)"
> echo " 2. mid3v2: sudo apt install python3-mutagen"
> echo " 3. kid3-cli: sudo apt install kid3-cli"
> echo " 4. exiftool: sudo apt install libimage-exiftool-perl"
> echo " 5. ffmpeg: sudo apt install ffmpeg (may not work on FAT32)"
> exit 1
> fi
> 
> echo ""
> echo "[INFO] Using tool: $TOOL_NAME"
> echo ""
> 
> # Check write permissions on current directory
> echo "[CHECK] Testing write permissions in current directory..."
> TEST_FILE=".artist_tag_fixer_test_$$"
> if touch "$TEST_FILE" 2>/dev/null; then
> rm -f "$TEST_FILE"
> echo "[OK] Write permissions confirmed"
> else
> echo "[ERROR] Cannot write to current directory!"
> echo "[INFO] This script needs write access to modify audio files."
> echo "[INFO] Current directory: $(pwd)"
> echo ""
> echo "[SUGGESTION] Try one of these solutions:"
> echo " 1. If on SD card/USB: sudo mount -o remount,rw /media/sam/THE_BIG_ONE"
> echo " 2. Copy files to home directory, modify there, then copy back"
> echo " 3. Run with sudo (not recommended for user files)"
> exit 1
> fi
> echo ""
> 
> # Warn if using ffmpeg on FAT32
> if ["$TOOL" = "ffmpeg"]; then
> FILESYSTEM=$(df -T . | tail -1 | awk '{print $2}')
> echo "[INFO] Detected filesystem: $FILESYSTEM"
> if [["$FILESYSTEM" =~ ^(vfat|fat|msdos|exfat)$]]; then
> echo "[WARN] You're using ffmpeg on a FAT filesystem ($FILESYSTEM)"
> echo "[WARN] ffmpeg may fail because it creates temporary files"
> echo "[WARN] STRONGLY RECOMMENDED: Install eyeD3 or mid3v2 instead:"
> echo " sudo apt install eyed3"
> echo ""
> read -p "[PROMPT] Continue anyway? (y/N): " -n 1 -r
> echo
> if [[! $REPLY =~ ^[Yy]$ ]]; then
> echo "[INFO] Exiting. Please install eyeD3 or mid3v2."
> exit 1
> fi
> fi
> fi
> echo ""
> 
> # Function to get artist tag based on tool
> get_artist() {
> local file="$1"
> case "$TOOL" in
> eyeD3)
> eyeD3 --no-color "$file" 2>/dev/null | grep -oP '(?<=artist: ).*' | head -1
> ;;
> mid3v2)
> mid3v2 -l "$file" 2>/dev/null | grep "TPE1=" | cut -d'=' -f2
> ;;
> kid3-cli)
> kid3-cli -c "get artist" "$file" 2>/dev/null | tail -1
> ;;
> exiftool)
> exiftool -Artist -s3 "$file" 2>/dev/null
> ;;
> ffmpeg)
> ffprobe -v quiet -show_entries format_tags=artist -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null
> ;;
> esac
> }
> 
> # Function to set artist tag based on tool
> set_artist() {
> local file="$1"
> local artist="$2"
> case "$TOOL" in
> eyeD3)
> eyeD3 --artist "$artist" --quiet "$file" 2>/dev/null
> ;;
> mid3v2)
> mid3v2 --artist "$artist" "$file" 2>/dev/null
> ;;
> kid3-cli)
> kid3-cli -c "set artist \"$artist\"" "$file" 2>/dev/null
> ;;
> exiftool)
> exiftool -Artist="$artist" -overwrite_original "$file" 2>/dev/null
> ;;
> ffmpeg)
> local temp_file="${file}.tmp"
> ffmpeg -i "$file" -metadata artist="$artist" -codec copy "$temp_file" 2>/dev/null && mv "$temp_file" "$file"
> ;;
> esac
> }
> 
> # Get current directory
> current_dir=$(pwd)
> echo "[INFO] Working directory: $current_dir"
> echo ""
> 
> # Count folders
> folder_count=$(find . -maxdepth 1 -type d ! -name "." ! -name ".*" | wc -l)
> echo "[INFO] Found $folder_count artist folder(s) to process"
> echo ""
> 
> # Process each directory
> processed_folders=0
> processed_files=0
> updated_files=0
> failed_updates=0
> 
> for artist_dir in */; do
> # Skip hidden directories
> [["$artist_dir" == .*]] && continue
>     
> # Remove trailing slash to get folder name
> artist_name="${artist_dir%/}"
>     
> processed_folders=$((processed_folders + 1))
>     
> echo "=========================================="
> echo "[FOLDER $processed_folders/$folder_count] Processing: '$artist_name'"
> echo "=========================================="
>     
> # Count files in this directory
> file_count=$(find "$artist_dir" -type f \( -iname "*.mp3" -o -iname "*.m4a" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.wav" \) | wc -l)
> echo "[INFO] Found $file_count audio file(s) in this folder"
> echo ""
>     
> if [$file_count -eq 0]; then
> echo "[WARN] No audio files found in '$artist_name', skipping..."
> echo ""
> continue
> fi
>     
> # Find all audio files recursively in this artist folder
> file_num=0
> find "$artist_dir" -type f \( -iname "*.mp3" -o -iname "*.m4a" -o -iname "*.flac" -o -iname "*.ogg" -o -iname "*.wav" \) | while read -r file; do
> file_num=$((file_num + 1))
>         
> echo "[FILE $file_num/$file_count] Checking: $file"
>         
> # Get current artist tag
> echo " [ACTION] Reading current artist tag using $TOOL_NAME..."
> current_artist=$(get_artist "$file")
>         
> if [-z "$current_artist"]; then
> echo " [INFO] No artist tag found (empty)"
> current_artist="(empty)"
> else
> echo " [INFO] Current artist tag: '$current_artist'"
> fi
>         
> # Check if artist tag matches folder name
> if ["$current_artist" != "$artist_name"]; then
> echo " [MISMATCH] Artist tag does not match folder name!"
> echo " [ACTION] Updating artist tag using $TOOL_NAME..."
> echo " FROM: '$current_artist'"
> echo " TO: '$artist_name'"
>             
> set_artist "$file" "$artist_name"
>             
> if [$? -eq 0]; then
> # Verify the update worked
> verify_artist=$(get_artist "$file")
> if ["$verify_artist" = "$artist_name"]; then
> echo " [SUCCESS] Artist tag updated and verified!"
> updated_files=$((updated_files + 1))
> else
> echo " [ERROR] Update appeared to succeed but verification failed!"
> echo " [DEBUG] Expected: '$artist_name', Got: '$verify_artist'"
> failed_updates=$((failed_updates + 1))
> fi
> else
> echo " [ERROR] Failed to update artist tag!"
> failed_updates=$((failed_updates + 1))
> fi
> else
> echo " [OK] Artist tag already matches folder name, no update needed"
> fi
>         
> echo ""
> processed_files=$((processed_files + 1))
> done
>     
> echo ""
> done
> 
> echo "=========================================="
> echo "Summary"
> echo "=========================================="
> echo "[COMPLETE] All folders processed!"
> echo "[TOOL] Used: $TOOL_NAME"
> echo "[STATS] Folders processed: $processed_folders"
> echo "[STATS] Files checked: $processed_files"
> echo "[STATS] Files updated successfully: $updated_files"
> echo "[STATS] Files failed to update: $failed_updates"
> echo ""
> 
> if [$failed_updates -gt 0]; then
> echo "[WARN] Some updates failed!"
> echo "[INFO] This is likely due to:"
> echo " - Filesystem limitations (FAT32/vfat with ffmpeg)"
> echo " - File permission issues"
> echo " - Incompatible file formats"
> echo ""
> echo "[SUGGESTION] Install eyeD3 for better FAT32 support:"
> echo " sudo apt install eyed3"
> echo ""
> fi
> 
> echo "Done!"
> 
> ```

---

<div class="post-metadata">

### Author: ![ars18](https://jtechforums.org/user_avatar/jtechforums.org/ars18/32/11805_2.png) [@ars18](https://jtechforums.org/u/ars18)
#### Post date: [January 20, 2026, 6:19am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/32 "2026-01-20T06:19:30Z")

</div>

A post was merged into an existing topic: [Share your Python scripts](https://jtechforums.org/t/share-your-python-scripts/5609)

---

<div class="post-metadata">

### Author: ![dfrydman](https://jtechforums.org/user_avatar/jtechforums.org/dfrydman/32/1947_2.png) [@dfrydman](https://jtechforums.org/u/dfrydman)
#### Post date: [January 16, 2026, 8:22pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/33 "2026-01-16T20:22:38Z")

</div>

Qin Device Identifiers script  
Automatically collects phone information (IMEI, Bluetooth address, WiFi address) and saves it to a text file. usefull for saving the correct info when flashing us bands and then using sn write tool to replace these identifiers

How to use:

1. Connect your phone to the computer and make sure ADB is connected
2. Run the script
3. Enter the person’s name when asked
4. Enter the WiFi MAC address when asked (find it in Settings \> About Phone)
5. Done! The information is saved to “imei numbers.txt”

> **Qin device identifiers script**
>
> ```auto
> @echo off
> setlocal enabledelayedexpansion
> 
> echo ========================================
> echo Device Information Collection Tool
> echo ========================================
> echo.
> 
> REM Check if ADB device is connected
> :check_device
> adb devices | findstr /R "unauthorized" >nul
> if !errorlevel! equ 0 (
> echo ERROR: Device detected but UNAUTHORIZED
> echo Please unlock your phone and approve the USB debugging prompt
> echo.
> pause
> echo Retrying...
> echo.
> goto :check_device
> )
> 
> adb devices | findstr /R "device$" >nul
> if errorlevel 1 (
> echo ERROR: No device detected
> echo Please connect your device and enable USB debugging
> echo.
> pause
> echo Retrying...
> echo.
> goto :check_device
> )
> 
> echo Device detected and authorized!
> echo.
> 
> echo Collecting device information...
> echo.
> 
> REM Create temp file
> set TEMP_FILE=%TEMP%\adb_device_info_%RANDOM%.txt
> 
> REM ===== Get IMEI =====
> echo [1/3] Getting IMEI...
> set IMEI=
> 
> REM Get IMEI using service call
> adb shell "service call iphonesubinfo 1" > "%TEMP_FILE%"
> 
> REM Extract IMEI from the ASCII parts (between single quotes)
> for /f "tokens=*" %%a in ('type "%TEMP_FILE%" ^| findstr "'"') do (
> set "line=%%a"
> REM Extract part after first quote
> for /f "tokens=2 delims='" %%b in ("!line!") do (
> set "part=%%b"
> REM Remove all dots and spaces
> set "part=!part:.=!"
> set "part=!part: =!"
> set IMEI=!IMEI!!part!
> )
> )
> 
> REM Clean IMEI - keep only digits
> set IMEI_TEMP=!IMEI!
> set IMEI=
> :extract_digits
> if defined IMEI_TEMP (
> set "char=!IMEI_TEMP:~0,1!"
> set "IMEI_TEMP=!IMEI_TEMP:~1!"
> if "!char!" geq "0" if "!char!" leq "9" (
> set IMEI=!IMEI!!char!
> )
> goto :extract_digits
> )
> 
> REM Take first 15 digits
> set IMEI=!IMEI:~0,15!
> 
> REM ===== Get Bluetooth MAC =====
> echo [2/3] Getting Bluetooth MAC address...
> set BT_MAC=
> 
> REM Get Bluetooth MAC from settings
> adb shell "settings get secure bluetooth_address" > "%TEMP_FILE%" 2>nul
> set /p BT_MAC=<"%TEMP_FILE%"
> 
> REM Remove colons and spaces
> set BT_MAC=!BT_MAC::=!
> set BT_MAC=!BT_MAC: =!
> call :lowercase BT_MAC
> 
> REM ===== Get WiFi MAC =====
> echo [3/3] Getting WiFi MAC address...
> set WIFI_MAC=
> 
> REM WiFi MAC cannot be read from Android without root
> echo WiFi MAC cannot be read from Android without root - will prompt for manual entry
> 
> REM Clean up temp file
> del "%TEMP_FILE%" 2>nul
> 
> echo.
> echo ========================================
> echo Auto-Collected Information:
> echo ========================================
> echo IMEI: !IMEI!
> echo Bluetooth MAC: !BT_MAC!
> echo WiFi MAC: !WIFI_MAC!
> echo ========================================
> echo.
> 
> REM Verify auto-collected data
> if "!IMEI!"=="" (
> echo ERROR: Failed to retrieve IMEI
> pause
> exit /b
> )
> if "!BT_MAC!"=="" (
> echo ERROR: Failed to retrieve Bluetooth MAC address
> pause
> exit /b
> )
> 
> REM Verify IMEI is 15 digits
> set IMEI_LENGTH=0
> set "temp=!IMEI!"
> :count_loop
> if defined temp (
> set /a IMEI_LENGTH+=1
> set "temp=!temp:~1!"
> goto :count_loop
> )
> 
> if !IMEI_LENGTH! neq 15 (
> echo WARNING: IMEI should be 15 digits but got !IMEI_LENGTH! digits
> echo IMEI: !IMEI!
> echo.
> set /p "CONTINUE=Continue anyway? (Y/N): "
> if /i "!CONTINUE!" neq "Y" (
> exit /b
> )
> )
> 
> REM Ask for WiFi MAC if not retrieved automatically
> if "!WIFI_MAC!"=="" (
> echo.
> echo ========================================
> echo WiFi MAC Manual Entry Required
> echo ========================================
> echo Please manually enter the WiFi MAC from Settings ^> About Phone
> echo ========================================
> echo.
> 
> :ask_wifi_mac
> set /p WIFI_MAC="Enter WiFi MAC address: "
> 
> REM Remove colons, spaces, and dashes if user entered them
> set WIFI_MAC=!WIFI_MAC::=!
> set WIFI_MAC=!WIFI_MAC:-=!
> set WIFI_MAC=!WIFI_MAC: =!
> call :lowercase WIFI_MAC
> 
> REM Verify WiFi MAC is 12 characters (6 bytes in hex)
> set WIFI_LENGTH=0
> set "temp=!WIFI_MAC!"
> :count_wifi
> if defined temp (
> set /a WIFI_LENGTH+=1
> set "temp=!temp:~1!"
> goto :count_wifi
> )
> 
> if !WIFI_LENGTH! neq 12 (
> echo ERROR: WiFi MAC should be 12 characters but got !WIFI_LENGTH!
> echo WiFi MAC: !WIFI_MAC!
> echo Please enter it again without colons or spaces
> echo.
> goto :ask_wifi_mac
> )
> )
> 
> REM Ask for person's name
> set /p PERSON_NAME="Enter the person's name: "
> 
> echo.
> echo ========================================
> echo Adding Entry:
> echo ========================================
> echo Name: !PERSON_NAME!
> echo IMEI: !IMEI!
> echo Bluetooth MAC: !BT_MAC!
> echo WiFi MAC: !WIFI_MAC!
> echo ========================================
> echo.
> 
> REM Create the entry
> set OUTPUT_FILE=%~dp0imei numbers.txt
> 
> REM Create file if it doesn't exist
> if not exist "!OUTPUT_FILE!" (
> echo Device Information Log > "!OUTPUT_FILE!"
> echo ======================== >> "!OUTPUT_FILE!"
> )
> 
> echo.>> "!OUTPUT_FILE!"
> echo !PERSON_NAME!>> "!OUTPUT_FILE!"
> echo imei - !IMEI!>> "!OUTPUT_FILE!"
> echo bluetooth address - !BT_MAC!>> "!OUTPUT_FILE!"
> echo wifi mac address - !WIFI_MAC!>> "!OUTPUT_FILE!"
> 
> echo.
> echo ========================================
> echo SUCCESS! Entry added to imei numbers.txt
> echo ========================================
> 
> exit /b
> 
> REM Subroutine to convert to lowercase
> :lowercase
> set %~1=!%~1:A=a!
> set %~1=!%~1:B=b!
> set %~1=!%~1:C=c!
> set %~1=!%~1:D=d!
> set %~1=!%~1:E=e!
> set %~1=!%~1:F=f!
> goto :eof
> 
> ```

---

<div class="post-metadata">

### Author: ![dfrydman](https://jtechforums.org/user_avatar/jtechforums.org/dfrydman/32/1947_2.png) [@dfrydman](https://jtechforums.org/u/dfrydman)
#### Post date: [January 16, 2026, 8:24pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/34 "2026-01-16T20:24:38Z")

</div>

i coudnt get the wifi mac address with regualr adb needs root dont know why

---

<div class="post-metadata">

### Author: ![ars18](https://jtechforums.org/user_avatar/jtechforums.org/ars18/32/11805_2.png) [@ars18](https://jtechforums.org/u/ars18)
#### Post date: [January 16, 2026, 8:39pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/35 "2026-01-16T20:39:33Z")

</div>

Was it connected to wifi?

---

<div class="post-metadata">

### Author: ![dfrydman](https://jtechforums.org/user_avatar/jtechforums.org/dfrydman/32/1947_2.png) [@dfrydman](https://jtechforums.org/u/dfrydman)
#### Post date: [January 16, 2026, 8:40pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/36 "2026-01-16T20:40:28Z")

</div>

yup

---

<div class="post-metadata">

### Author: ![dfrydman](https://jtechforums.org/user_avatar/jtechforums.org/dfrydman/32/1947_2.png) [@dfrydman](https://jtechforums.org/u/dfrydman)
#### Post date: [January 16, 2026, 8:41pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/37 "2026-01-16T20:41:05Z")

</div>

i could see it in about phone. i even tried having claude read the screen but it wasnt going well also probalby wouldnt work as a script

---

<div class="post-metadata">

### Author: ![ars18](https://jtechforums.org/user_avatar/jtechforums.org/ars18/32/11805_2.png) [@ars18](https://jtechforums.org/u/ars18)
#### Post date: [January 16, 2026, 8:46pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/38 "2026-01-16T20:46:06Z")

</div>

So am start that settings activity, input swipe (figure out measurement) and take screencap with adb 🙂

Yeshivish

---

<div class="post-metadata">

### Author: ![dfrydman](https://jtechforums.org/user_avatar/jtechforums.org/dfrydman/32/1947_2.png) [@dfrydman](https://jtechforums.org/u/dfrydman)
#### Post date: [January 16, 2026, 8:56pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/39 "2026-01-16T20:56:53Z")

</div>

exactly what i tried. but how do you make a shell script read a screenshot

---

<div class="post-metadata">

### Author: ![ars18](https://jtechforums.org/user_avatar/jtechforums.org/ars18/32/11805_2.png) [@ars18](https://jtechforums.org/u/ars18)
#### Post date: [January 16, 2026, 8:59pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/40 "2026-01-16T20:59:12Z")

</div>

Ah, good point. I was just thinking to save it in the folder.

---

<div class="post-metadata">

### Author: ![Shalom\_Karr](https://jtechforums.org/user_avatar/jtechforums.org/shalom_karr/32/8264_2.png) [@Shalom\_Karr](https://jtechforums.org/u/Shalom_Karr)
#### Post date: [January 20, 2026, 6:11am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/41 "2026-01-20T06:11:17Z")

</div>

A post was merged into an existing topic: [Share your shell/bash/bat scripts for Python](https://jtechforums.org/t/share-your-shell-bash-bat-scripts-for-python/5609/2)

---

<div class="post-metadata">

### Author: ![flipphoneguy](https://jtechforums.org/user_avatar/jtechforums.org/flipphoneguy/32/11165_2.png) [@flipphoneguy](https://jtechforums.org/u/flipphoneguy)
#### Post date: [January 20, 2026, 12:22am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/42 "2026-01-20T00:22:41Z")

</div>

[@moderators](https://jtechforums.org/groups/moderators) can we move the python scripts into a new topic similar to this 1 but for python scripts? I think its its own thing. Obviously also only for cli style scripts… (not just random gui apps that happened to have been written in python)

---

<div class="post-metadata">

### Author: ![DaWelch](https://jtechforums.org/user_avatar/jtechforums.org/dawelch/32/5235_2.png) [@DaWelch](https://jtechforums.org/u/DaWelch)
#### Post date: [January 20, 2026, 6:08am UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/44 "2026-01-20T06:08:15Z")

</div>

> [@Share your Python scripts](https://jtechforums.org/t/share-your-python-scripts/5609/3):
>
> Here’s a simple python script for 2fa.

This

---

<div class="post-metadata">

### Author: ![flipphoneguy](https://jtechforums.org/user_avatar/jtechforums.org/flipphoneguy/32/11165_2.png) [@flipphoneguy](https://jtechforums.org/u/flipphoneguy)
#### Post date: [February 24, 2026, 4:58pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/46 "2026-02-24T16:58:17Z")

</div>

My personal wrapper for yt-dlp instead of remembering their complex options which I usually need to download.

Uses basic option for downloading with thumbnail and metadata. Allows basic arguments like output directory quiet mode video or audio etc. Just see usage at the top of the script.

```bash
#!/usr/bin/env bash

# Dependencies: yt-dlp, ffmpeg

usage() {
    cat <<EOF
Usage: $(basename "$0") [-a|-v] [-q] [-o DIR] [TITLE|URL]

A yt-dlp wrapper for downloading audio or video from YouTube.

Options:
  -a, --audio Download as MP3 audio (default)
  -v, --video Download as MP4 video (720p)
  -q, --quiet Suppress yt-dlp output, show only status messages
  -o, --output DIR Output directory (must exist)
  -h, --help Show this help message

Arguments:
  URL Download directly from a YouTube URL
  TITLE Search YouTube and pick from 7 results

If no arguments are given, you will be prompted for format and title/URL.

Dependencies:
  yt-dlp https://github.com/yt-dlp/yt-dlp
  ffmpeg https://ffmpeg.org
EOF
}

quiet=0 outdir=""
rq='^--?q(uiet)?$' ro='^--?o(utput)?$'

# Pre-scan for -q and -o so they can appear anywhere
args=()
while [[$# -gt 0]]; do
    if [["$1" =~ $rq]]; then
        quiet=1
    elif [["$1" =~ $ro]]; then
        if [[-z "$2" || "$2" == -*]]; then
            echo "Error: --output requires a directory path" >&2; exit 1
        fi
        if [[! -d "$2"]]; then
            echo "Error: output directory does not exist: $2" >&2; exit 1
        fi
        outdir="$2"; shift
    elif [["$1" =~ ^--?h(elp)?$]]; then
        usage; exit 0
    else
        args+=("$1")
    fi
    shift
done
set -- "${args[@]}"

declare -a cmd=(yt-dlp -x --audio-format mp3 --embed-metadata --embed-thumbnail --no-playlist)
rv='^--?v(id(eo)?)?$' ra='^--?a(ud(io)?)?$'

if [[$# -eq 0]]; then
    read -rp "Format - (a)udio or (v)ideo: " fmt
    [["${fmt/quit/q}" == "q"]] && exit 0
    read -rp "Title, URL, or q to quit: " query
    [["${query/quit/q}" == "q"]] && exit 0
    set -- "$fmt" "$query"
fi

if [["$1" =~ $rv || "${@: -1}" =~ $rv]]; then
    cmd=(yt-dlp -S "res:720" --merge-output-format mp4 --embed-metadata --embed-thumbnail --no-playlist)
    [["$1" =~ $rv]] && shift || set -- "${@:1:$#-1}"
fi
if [["$1" =~ $ra || "${@: -1}" =~ $ra]]; then
    [["$1" =~ $ra]] && shift || set -- "${@:1:$#-1}"
fi

[[$quiet -eq 1]] && cmd+=(--quiet --no-warnings)
[[-n "$outdir"]] && cmd+=(-P "$outdir")

if [[-z "$2" && "${1:0:8}" == "https://"]]; then
    [[$quiet -eq 1]] && echo "Downloading..."
    "${cmd[@]}" "$1"
    exit 0
fi
if [["${1:0:8}" != "https://"]]; then
    declare -a res
    [[$quiet -eq 1]] && echo "Searching..."
    mapfile -t res < <(yt-dlp "ytsearch7:$*" -O "%(id)s|%(title)s - %(uploader)s (%(duration_string)s)")
    for ((i=0; i<${#res[@]}; i++)); do echo "$((i+1)). ${res[i]#*|}"; done
    read -rp "Please pick a number (1-${#res[@]}) or q: " ans
    [["${ans/quit/q}" == "q"]] && exit 0
    [[$quiet -eq 1]] && echo "Downloading..."
    "${cmd[@]}" "https://youtu.be/${res[$((ans-1))]%|*}"
fi

```

---

<div class="post-metadata">

### Author: ![anon24812444](https://jtechforums.org/letter_avatar_proxy/v4/letter/a/e495f1/32.png) [@anon24812444](https://jtechforums.org/u/anon24812444)
#### Post date: [March 17, 2026, 8:46pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/47 "2026-03-17T20:46:02Z")

</div>

```auto
mdtable() {
  cols=$(echo $1 | cut -dx -f1)
  rows=$(echo $1 | cut -dx -f2)
  header=$(for i in $(seq 1 $cols); do printf "| col$i "; done; echo "|")
  divider=$(for i in $(seq 1 $cols); do printf "|------"; done; echo "|")
  row=$(for i in $(seq 1 $cols); do printf "| "; done; echo "|")
  result="$header\n$divider"
  for r in $(seq 1 $rows); do
    result="$result\n$row"
  done
  echo "$result" 
}

```

* * *

### add to your ~/.zshrc or whatever shell you use
  

input ⬇

```auto
mdtable 4x6

```

output ⬇

```auto
| col1 | col2 | col3 | col4 |
|------|-------|-----|-----|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |

```

* * *

#### non formmated

| col1 | col2 | col3 | col4 |
| --- | --- | --- | --- |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |

* * *

### add a pipe ` | $CLIPBOARD ` at the end to save to clipboard (silently)

---

<div class="post-metadata">

### Author: ![anon24812444](https://jtechforums.org/letter_avatar_proxy/v4/letter/a/e495f1/32.png) [@anon24812444](https://jtechforums.org/u/anon24812444)
#### Post date: [March 24, 2026, 3:48pm UTC](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017/48 "2026-03-24T15:48:54Z")

</div>

ever copied a prompt and the silly `$` tripped everything up?

* * *

no \_prompt\_prompt.sh

if first character is a `$` it ditches it

```auto
	
	#!/usr/bin/env sh
	# no_dollar.sh — Strip a leading '$' from commands before execution
	# Works with: zsh, bash, and most POSIX-compatible shells
	#
	# INSTALL (pick your shell):
	# zsh: echo 'source ~/no_dollar.sh' >> ~/.zshrc && source ~/.zshrc
	# bash: echo 'source ~/no_dollar.sh' >> ~/.bashrc && source ~/.bashrc
	#
	# HOW IT WORKS:
	# Hooks into the shell's pre-execution phase. If the first non-space
	# character of your command is '$', it's silently stripped and the
	# rest runs normally.
	#
	# Example:
	# $ ls -la → runs: ls -la
	# $git status → runs: git status
	# $ echo "hello" → runs: echo "hello"
	
	# ── zsh ──────────────────────────────────────────────────────────────────────
	if [-n "$ZSH_VERSION"]; then
	  # zsh exposes the typed command via $BUFFER in preexec hooks.
	  # We use a preexec function to rewrite the command before execution.
	  _no_dollar_preexec() {
	    : # no-op — rewriting happens at read time via zle widget below
	  }
	
	  # Override the accept-line widget so the line is rewritten before execution
	  _no_dollar_accept_line() {
	    local stripped="${BUFFER#"${BUFFER%%[!]*}"}" # lstrip spaces
	    if [["$stripped" == \$*]]; then
	      BUFFER="${stripped:1}" # drop the '$'
	    fi
	    zle .accept-line # call the real accept-line
	  }
	
	  zle -N accept-line _no_dollar_accept_line
	
	# ── bash ─────────────────────────────────────────────────────────────────────
	elif [-n "$BASH_VERSION"]; then
	  # bash doesn't have a pre-exec ZLE equivalent, so we wrap the DEBUG trap.
	  # The trick: rewrite $BASH_COMMAND isn't possible, but we CAN use a
	  # function that bash calls via the prompt command to sanitise readline input.
	  #
	  # Approach: override the readline binding for Return so we can preprocess.
	  # Since bash readline is harder to hook cleanly, we use a PROMPT_COMMAND
	  # trick with `history` to detect and warn, combined with a bash function
	  # alias fallback that covers the most common case.
	
	  # Primary method: bind Return to a bash function via readline macro
	  # This covers interactive input in bash 4.0+
	  _no_dollar_run() {
	    local cmd
	    # Read the current readline buffer via builtin
	    cmd="$(history 1 | sed 's/^[[:space:]]*[0-9]*[[:space:]]*//')"
	    local stripped="${cmd#"${cmd%%[!]*}"}"
	    if [["$stripped" == \$*]]; then
	      local clean="${stripped:1}"
	      # Replace the history entry and re-run
	      history -s "$clean"
	      eval "$clean"
	    fi
	  }
	
	  # Fallback: command_not_found_handle catches `$ git status` style mistakes
	  # where the shell tries to run a command literally named '$'
	  command_not_found_handle() {
	    # Called when the shell can't find a command named e.g. '$'
	    # Reconstruct the rest of the args as the real command
	    if [["$1" == '$']] && [[$# -gt 1]]; then
	      shift
	      "$@"
	      return $?
	    fi
	    # Default not-found message for everything else
	    echo "bash: $1: command not found" >&2
	    return 127
	  }
	
	  # Also handle: user types `$ ls` → shell tries to exec a binary named `$`
	  # The command_not_found_handle above catches this cleanly in bash 4+.
	  :
	fi
	# ─────────────────────────────────────────────────────────────────────────────

```

add as plugin and source or just dump it in your ~/.whatevershellyouuserc

[Previous page](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017.md?page=1)

[Next page](https://jtechforums.org/t/share-your-shell-bash-bat-scripts/4017.md?page=3)
