1

First of all, I've got no background in programming and do this as a hobby in my spare time. And by that i mean: It's a "hobby", i do it for fun. I began like 6 weeks ago, everything script-like here is a mixture of internet research and/or looking at code and figuring out what happens when running set -xe plus trial and error approach, so don't expect overly awesome coding and me asking "silly" questions.

So I have a script, which lets you:

  1. Choose one (required: system partition) or two (optional: data partition) flashfire (android) backups,
  2. Export paths and creates six folders (project_folder, project_folder/rom, project_folder/rom/data, projevt_folder/rom/system and two more)
  3. Rejoins the parts of the backup (it's split at 1.07gb) into data or system folder and
  4. Changes directory to .../system or .../data and extracts the backups inside data or system folder

This all works pretty well except for changing directory to project_folder/rom/data.

It always says:

cd: ./project_folder/rom/data: No such file or directory

Interestingly project_folder/rom/system works and also rejoining the backup into the data folder works. Why does changing directory not work as soon as the script should change to data folder?

Here the part that won't work (system works, data won't):

EXT_SYS() {
# extract backups
echo "Extracting :"

echo "System partition backup..."
cd "$ACTIVE_DB/rom/system"
lz4 -dc --no-sparse system.tar.lz4 | tar xf -
}

EXT_DATA() {
# extract backups
echo "Data partition backup..."
cd "$ACTIVE_DB/rom/data"
lz4 -dc --no-sparse data.tar.lz4 | tar xf -
}

and the rest of it

#!/bin/bash

PRINT_LINE3
echo "To create a DB make sure that you have:"
echo
echo "[REQUIRED] system.tlz4 and all system.*.tlz4 "
echo "[OPTIONAL] data.tlz4 and all data.*.tlz4"    
echo "in $BASE_DIR"
echo

local READY=0
while [[ $READY -eq 0 ]]; do
    echo
    echo "Please fill a path for your system.tlz4 file"
    echo "Potential candidates:"
    echo "=-=-=-=-=-=-=-=-="
    find ./base_drops -type f -iname "system.tlz4"
    echo "=-=-=-=-=-=-=-=-="
    read -p "system.tlz4: " SYSTEM_BAK

    echo
    echo "Please fill a path for your data.tlz4 file. Leave empty if none."
    echo "Potential candidates:"
    echo "=-=-=-=-=-=-=-=-="
    find ./base_drops -type f -iname "data.tlz4"
    echo "=-=-=-=-=-=-=-=-="
    read -p "data.tlz4: " DATA_BAK

    if [[ -f "$SYSTEM_BAK" ]] && ([[ -z "$DATA_BAK" || -f "$DATA_BAK" ]]); then
        READY=1
    else
        echo "Some of your files do not exist"
        PRESS_ENTER
    fi
done
# creates db dir plus subdirs if needed
PRINT_LINE3
read -p "Name your database: " NAME
echo
echo "backups: "
if [ -f  "$SYSTEM_BAK" ] ; then
    echo "  [SYS]  -> $SYSTEM_BAK"
fi
if [ -f  "$DATA_BAK" ] ; then
    echo "  [DATA] -> $DATA_BAK"
else
    echo "  no DATA "
fi
PRINT_LINE1
export ACTIVE_DB="./DB_$NAME"
export LIST_DIR="$ACTIVE_DB/lists"
export LOGS_DIR="$ACTIVE_DB/logs"
export ROM_DIR="$ACTIVE_DB/rom"
export SYS_DIR="$ACTIVE_DB/rom/system"
if [[ ! -z ${DATA_BAK+x} ]] ; then
    export DATA_DIR="$ACTIVE_DB/rom/data"
fi
echo "Creating $ACTIVE_DB, please wait..."
mkdir -p "$ACTIVE_DB"
mkdir -p "$LIST_DIR"
mkdir -p "$LOGS_DIR"
mkdir -p "$SYS_DIR"
if [[ ! -z "$DATA_BAK" ]] ; then  
   mkdir -p "$DATA_DIR"
fi
# SYSTEM
# find backup parts
echo "Merging: "
echo -n "System partition "
if [[ -f "./base_drops/system.0004.tlz4" ]] ; then
   export SYSTEM_BAK4="./base_drops/system.0004.tlz4"
   export SYSTEM_BAK3="./base_drops/system.0003.tlz4"
   export SYSTEM_BAK2="./base_drops/system.0002.tlz4" 
   cat "$SYSTEM_BAK" "$SYSTEM_BAK2" "$SYSTEM_BAK3" "$SYSTEM_BAK4" > "$ACTIVE_DB/rom/system/system.tar.lz4"        
   echo "(4 parts) -> $SYSTEM_BAK $SYSTEM_BAK2 $SYSTEM_BAK3 $SYSTEM_BAK4"    
else
    if [[ -f "./base_drops/system.0003.tlz4" ]] ; then
        export SYSTEM_BAK3="./base_drops/system.0003.tlz4"
        export SYSTEM_BAK2="./base_drops/system.0002.tlz4"  
        cat "$SYSTEM_BAK" "$SYSTEM_BAK2" "$SYSTEM_BAK3" > "$ACTIVE_DB/rom/system/system.tar.lz4"
        echo "(3 parts) -> $SYSTEM_BAK $SYSTEM_BAK2 $SYSTEM_BAK3"    
    else
        if [[ -f "./base_drops/system.0002.tlz4" ]] ; then
            export SYSTEM_BAK2="./base_drops/system.0002.tlz4"  
            cat "$SYSTEM_BAK" "$SYSTEM_BAK2" > "$ACTIVE_DB/rom/system/system.tar.lz4"
            echo "(2 parts) -> $SYSTEM_BAK $SYSTEM_BAK2"    
        fi
    fi
fi    
# /DATA-Partition backup
if [[ ! -z ${DATA_BAK+x} ]] ; then
echo -n  "Data partition:"
    if [[ -f "./base_drops/data.0004.tlz4" ]] ; then       # check for backup split-archive parts
        export DATA_BAK4="./base_drops/data.0004.tlz4"
        export DATA_BAK3="./base_drops/data.0003.tlz4"
        export DATA_BAK2="./base_drops/data.0002.tlz4"
        cat "$DATA_BAK" "$DATA_BAK2" "$DATA_BAK3" "$DATA_BAK4" > "$ACTIVE_DB/rom/data/data.tar.lz4"        # join into one archive
        echo "(4 parts) -> $DATA_BAK $DATA_BAK2 $DATA_BAK3 $DATA_BAK4"    
    else 
        if [[ -f "./base_drops/data.0003.tlz4" ]] ; then
            export DATA_BAK3="./base_drops/data.0003.tlz4"
            export DATA_BAK2="./base_drops/data.0002.tlz4"
            cat "$DATA_BAK" "$DATA_BAK2" "$DATA_BAK3" > "$ACTIVE_DB/rom/data/data.tar.lz4"
            echo "(3 parts) -> $DATA_BAK $DATA_BAK2 $DATA_BAK3"    
        else
            if [[ -f "./base_drops/data.0002.tlz4" ]] ; then
                export DATA_BAK2="./base_drops/data.0002.tlz4"
                cat "$DATA_BAK" "$DATA_BAK2" > "$ACTIVE_DB/rom/data/data.tar.lz4"
                echo "(2 parts) -> $DATA_BAK $DATA_BAK2"    
            fi
        fi
    fi
fi
EXT_SYS
EXT_DATA
# clean up
cd "$MAIN_DIR"
if [[ ! -z ${DATA_BAK+x} ]] ; then
    rm -f "$ACTIVE_DB/rom/data/data.tar.lz4"
    rm -f "$DATA_BAK1" 
    rm -f "$DATA_BAK2" 
    rm -f "$DATA_BAK3" 
    rm -f "$DATA_BAK4"
    rm -f "$ACTIVE_DB/rom/system/system.tar.lz4"
    rm -f "$SYSTEM_BAK1" 
    rm -f "$SYSTEM_BAK2" 
    rm -f "$SYSTEM_BAK3" 
    rm -f "$SYSTEM_BAK4"
else        
    rm -f "$ACTIVE_DB/rom/system/system.tar.lz4"
    rm -f "$SYSTEM_BAK1" 
    rm -f "$SYSTEM_BAK2" 
    rm -f "$SYSTEM_BAK3" 
    rm -f "$SYSTEM_BAK4"  
fi
echo "."
PRESS_ENTER
  • 1
    Stripping away the extra verbosity, you are starting from one directory, cding into a subdirectory, and then trying to cd into a different subdirectory of the first directory—right? Perhaps you should use cd - to return to the first directory before using another relative path relative to it. – Wildcard Feb 16 '16 at 17:11
  • That's what i try to do^^ As i understand it right now, the only problem is is that i cd into system dir and didn't cd back to topdir before cding into data dir? All i know i've learned while doing this, so i'm like noob^10, but shouldn't it be enough that i've exported the project_folder path? – chris Feb 16 '16 at 17:20
  • Since your code snippet only shows function definitions and doesn't show any functions being called, it's awfully hard to diagnose it properly. I don't know why you are exporting a path or what you hope to gain by doing it; I don't think you understand what export does but without more context it's impossible to be sure. – Wildcard Feb 16 '16 at 17:23
  • Yep, gonna add the whole thing and yeah it actually is like i don't know what i do here the most time as i've never learned programming – chris Feb 16 '16 at 17:26
  • If you are writing complex shell scripts, consider using a scripting language instead (most Linux distributions use Python for much administration tools, so learning/using that is always useful; some people like Perl's expressiveness better). Shell is designed as an interactive command interpreter, that isn't completely horrible for stand-alone scripts. It is often used because a shell is guaranteed to be available, not because it is a good tool for the job. – vonbrand Feb 16 '16 at 19:36
2

There are a variety of options; I tend to use subshells

( cd some/dir && do_work )
( cd some/other/dir && do_more_work )

As the pwd will only change within the subshell, not in the parent process. Another option is pushd/popd:

pushd some/dir
do_work
popd
pushd some/other/dir
do_even_more_work

And still another is to use fully qualified paths, which have the bonus of not caring where the previous working directory was, though do moreso tie the code to a particular filesystem hierarchy:

WORKDIR=/blah/de/blah
cd $WORKDIR/some/dir && do_work
cd $WORKDIR/some/other/dir && you_get_the_idea

Error checking is also handy, as cd may fail and then what happens? Always check that the cd happened (the && ... test) or use set -e to bail on any fail.

  • pushd/popd did work, as did the subshell variant. i'm gonna stick with the subshell variant. Thank you so ******* much – chris Feb 16 '16 at 19:12
  • @chris, pushd/popd work in the same shell, (some command here) starts a new shell. That takes some time (might not be relevant), but also isolates effects like changing variables in it (and directory changes, obviously). – vonbrand Feb 16 '16 at 19:34
  • In this case, all that is done is extracting a *.tar.lz4, no variables are set and the time thingy doesn't matter, at least to me. Nonetheless, thanks for clarifying this, gonna keep this in mind – chris Feb 16 '16 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.