首页 > 解决方案 > 突然无法运行 Shell 脚本功能

问题描述

我有一个名为“wpautobuild.sh”的文件。在该文件中,我有一个脚本,可以在 linux 服务器上自动设置开发环境和网站。

我一直wp_auto_build()在使用以下命令调用脚本中命名的函数:

$ ./wpautobuild.sh; wp_auto_build --project=abctest1

在我关闭终端会话并重新启动它之前,这一直很好。现在,当我运行相同的命令时,出现以下错误:

-jailshell: wp_auto_build: command not found

我不知道为什么我可以运行它一段时间,但现在我不能。文件中没有任何变化。诚然,我在编写 shell 脚本方面经验不足。

这是 wpautobuild.sh:

#!/bin/sh

###########
# Variables
###########

#Required Variables
#BashRC File
FILE_BASH="$HOME/.bashrc";
FILE_WPAB="$HOME/wpautobuild.sh";

#The parent folder for all your site files
PATH_DEV="/home/wm/public_html";

#MYSQL Variables
MYSQL_UN="someuser";
MYSQL_PW="somepass";

#Repositories
declare -A REPO_PATH;
REPO_PATH[jumpstart]="https://someuser@bitbucket.org/someuser/wp-jumpstart.git";
REPO_PATH[divi]="https://someuser@bitbucket.org/someuser/divilib.git";

declare -A WP_DB_PREFIX;
WP_DB_PREFIX[jumpstart]="wp_";
WP_DB_PREFIX[divi]="wp_";


#Color variables

GREEN="\033[0;32m";
RED="\033[0;31m";
BLUE="\033[0;34m";
NC="\033[0m"; # No Color

BOLD="\e[1m";

WPAB_CHECKED=false;

#configurable variables
PROJECT_NAME="";

BUILD_TYPE="divi";

DB_NAME="";
DB_FILE_NAME="";

DB_SR_SEARCH="";
DB_SR_REPLACE="";

##############
# Functions
##############

####################################
# WP Build Automation
####################################
handle_arguments() {

    ARGUMENTS=($@);

    for i in "${ARGUMENTS[@]}"
        do

            INDEX=`expr index "$i" =`;

            case $i in
                --project*)
                    PROJECT_NAME=${i:INDEX};
                ;;
                --build*)
                    BUILD_TYPE=${i:INDEX};
                ;;
                --dbname*)
                    DB_NAME=${i:INDEX};
                ;;
                --mysqlun*)
                    MYSQL_UN=${i:INDEX};
                ;;
                --mysqlpw*)
                    MYSQL_PW=${i:INDEX};
                ;;
                --dbfilename*)
                    DB_FILE_NAME=${i:INDEX};
                ;;
                --search*)
                    DB_SR_SEARCH=${i:INDEX};
                ;;
                --replace*)
                    DB_SR_REPLACE=${i:INDEX};
                ;;
                *)
                    echo -e "${RED}$i is not recognized as an argument.${NC}\n";
                ;;
            esac
    done;

    if [[ -z $DB_NAME ]];
        then
            DB_NAME=$PROJECT_NAME;
    fi

}




wp_auto_build() {

    # The main script that runs all the necessary functions to set up a site
    #
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; determines directory name, domain, and db name
    #
    #  --build      - [optional]
    #               - [values] - jumpstart, divi
    #               - [default] - jumpstart
    #               - determines whether to install wp-jumpstart or divilib
    #
    #  --dbname     - [optional]
    #               - [default] - --project
    #               - determines the name of the database

    TIMESTAMP_START=$( date +%s );
    
    printf "\n\n${BLUE}${BOLD}****************************************\n";
    printf "WP Autobuild Sarting Up...\n";
    printf "****************************************${NC}\n\n";
    

    #check argument number
    if [ $# -eq 0 ]
        then
            printf "${RED}[FAILED]  No arguments passed. --project is required.\n";
            return;
    fi

    handle_arguments $@;

    echo ;
    echo "***********************************";
    echo "Checking Current Configuration...";
    echo "***********************************";
    echo ;

    # Check variables
    check_config;
    #checks the return code of check_config to make sure everything is good. If not stop script
    if [ $? -eq 1 ]
        then
            return;
        else
            printf "\n${GREEN}Variables are good${NC}\n\n"
    fi

    # Check configure to make sure all commands and dependencies are there
    check_CLI_dependencies;
    #checks the return code of check_CLI_dependencies to make sure everything is good. If not stop script
    if [ $? -eq 1 ]
        then
            return;
        else
            printf "\n${GREEN}Dependencies are good${NC}\n\n"
    fi

    WPAB_CHECKED=true;

    echo "Please check the configuration. Type "Y" and then hit [ENTER] to continue; anything else to stop...";
    read CONTINUE;

    if [[ $CONTINUE != "Y" ]]; then
        return
    fi


    printf "\n***********************************\n";
    printf "Starting: WP Auto-Build...\n";
    printf "***********************************\n";

    #Setup subdomain
    setup_subdomain;

    #Setup Build DB
    setup_build_DB;

    #Search and Replace Build DB
    run_SRDB;

    #Update Plugins and Core
    run_wp_update;
    
    # Open in browser
    open_wpab_site;

    TIMESTAMP_END=$( date +%s );

    RUNTIME=$(($TIMESTAMP_END - $TIMESTAMP_START));

    printf "${GREEN}\n";
    printf "***********************************\n";
    printf "Done: WP Auto-Build...\n";
    printf "Time: $RUNTIME secs\n";
    printf "***********************************\n";
    printf "${NC}\n";

}

setup_subdomain() {
    #
    # Adds a directory for the project and adds an alias in bash goto_{--project}.
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; deteremines directory name, domain, and db name
    #

    # if false, then we are running the function individually and need to supply arguments, handle arguments and check variables
    if [ $WPAB_CHECKED == 'false' ]
        then
            handle_arguments $@;

            # ########################
            # ADD INDIVIDUAL CHECKS
            # ########################
    fi

    printf "${GREEN}Setting up subdomain for site...\n";
    printf "************************************${NC}\n";

    # Create subdomain using cpanel api
    uapi --user=someuser SubDomain addsubdomain domain=$PROJECT_NAME rootdomain=somedomain.com dir=%2Fpublic_html%2F$PROJECT_NAME

}


setup_build() {
    # Clones the build repository, deletes the git and then reinitializes it.
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; deteremines directory name, domain, and db name
    #
    #  --build      - [optional]
    #               - [values] - jumpstart, divi
    #               - [default] - jumpstart
    #               - determines whether to install wp-jumpstart or divilib


    # if false, then we are running the function individually and need to supply arguments, handle arguments and check variables
    if [ $WPAB_CHECKED == 'false' ]
        then
            handle_arguments $@;

            # ########################
            # ADD INDIVIDUAL CHECKS
            # ########################
    fi

    printf "\n${GREEN}Cloning $BUILD_TYPE repository...\n";
    printf "*****************************************${NC}";

    cd "$PATH_DEV/$PROJECT_NAME";

    echo "";

    #Clone Repository
    git clone ${REPO_PATH[$BUILD_TYPE]} "$PATH_DEV/$PROJECT_NAME";

    #Remove repository .git so we can reinitialize it
    rm -rf "$PATH_DEV/$PROJECT_NAME/.git";

}

setup_build_DB() {
    #
    # Sets up WP wp-config.php file and WP database based on the file in .dev/sql
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; deteremines directory name, domain
    #
    # --dbname      - [required]
    #               - name of the databsae;
    #
    # --build       - [required]
    #               - [values] - jumpstart, divi
    #               - [default] - jumpstart
    #               - database table prefix
    #
    # --mysqlun     - [optional]
    #               - override default MYSQL_UN;
    #
    # --mysqlpw     - [optional]
    #               - override default MYSQL_PW;
    #

    # if false, then we are running the function individually and need to supply arguments, handle arguments and check variables
    if [ $WPAB_CHECKED == 'false' ]
        then
            handle_arguments $@;

            # ########################
            # ADD INDIVIDUAL CHECKS
            # ########################
    fi

    cd "$PATH_DEV/$PROJECT_NAME";

    printf "\n${GREEN}Creating database...\n";
    printf "*****************************************${NC}\n";

    #create db
    uapi --user=someuser Mysql create_database name=wm_$PROJECT_NAME
    
    printf "\n${GREEN}Assigning user to database...\n";
    printf "*****************************************${NC}\n";
    
    #assign user
    uapi --user=someuser Mysql set_privileges_on_database user=dbuser database=wm_$PROJECT_NAME privileges=DELETE,UPDATE,CREATE,ALTER
    
    printf "\n${GREEN}Importing database from .dev/sql directory...\n";
    printf "*****************************************${NC}\n";
    
    if [ $BUILD_TYPE == 'jumpstart' ]; then
        wp db import "$PATH_DEV/$PROJECT_NAME/.dev/sql/wpjs-c8631c0.sql";
    elif [ $BUILD_TYPE == 'divi' ]; then
        wp db import "$PATH_DEV/$PROJECT_NAME/.dev/sql/divilib.sql";
    fi

}

run_SRDB() {
    #
    # Ruin SRDB on the database
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; deteremines directory name, domain
    #
    # --dbname      - [required]
    #               - name of the databsae;
    #
    # --build       - [required]
    #               - [values] - jumpstart, divi
    #               - [default] - jumpstart
    #               - database table prefix
    #
    # --mysqlun     - [optional]
    #               - override default MYSQL_UN;
    #
    # --mysqlpw     - [optional]
    #               - override default MYSQL_PW;

    # if false, then we are running the function individually and need to supply arguments, handle arguments and check variables
    if [ $WPAB_CHECKED == 'false' ]
        then
            handle_arguments $@;

            # ########################
            # ADD INDIVIDUAL CHECKS
            # ########################
    fi

    printf "\n${GREEN}Running Search & Replace for URL...\n";
    printf "*****************************************${NC}\n";


    #cd "$PATH_DEV/$PROJECT_NAME/srdb";

    if [ $BUILD_TYPE == 'jumpstart' ]; then
        wp search-replace 'wpjs.local' "$PROJECT_NAME.somedomain.com"
    elif [ $BUILD_TYPE == 'divi' ]; then
        wp search-replace 'divilib.local' "$PROJECT_NAME.somedomain.com"
    fi
}

run_wp_update() {
    #
    # Update Wordpress and Plugins
    #
    # Arguments
    # --project     - [required]
    #               - name of the project; deteremines directory name, domain
    #
    # --build       - [required]
    #               - [values] - jumpstart, divi
    #               - [default] - jumpstart
    #               - database table prefix


    # if false, then we are running the function individually and need to supply arguments, handle arguments and check variables
    if [ $WPAB_CHECKED == 'false' ]
        then
            handle_arguments $@;

            # ########################
            # ADD INDIVIDUAL CHECKS
            # ########################
    fi

    cd "$PATH_DEV/$PROJECT_NAME";
    
    #Update Core
    
    printf "\n${GREEN}Updating WP Core...\n";
    printf "*****************************************${NC}\n";
    
    wp core update;

    #Update All Plugins
    
    printf "\n${GREEN}Updating WP Plugins...\n";
    printf "*****************************************${NC}\n";
    
    wp plugin update --all;
    
    #Update All Themes
    
    printf "\n${GREEN}Updating WP Themes...\n";
    printf "*****************************************${NC}\n";
    
    wp theme update --all;
    
}


check_config() {
    WPAB_STATUS=true;

    echo "Required Variables...";
    echo "***********************************";

    #Project Name
    if [ -z "$PROJECT_NAME" ]
        then
            printf "${RED}[FAILED]  PROJECT_NAME is empty. This must be passed with --project.\n";
            WPAB_STATUS=false;
        else

            #Site files
            if [ -d "$PATH_DEV/$PROJECT_NAME" ]
                then
                    printf "${RED}[FAILED]  $PATH_DEV/$PROJECT_NAME is already a project directory.${NC}\n";
                    WPAB_STATUS=false;
                else
                    printf "${GREEN}[SUCCESS]   PROJECT_NAME:       $PROJECT_NAME${NC}\n";
            fi

    fi

    #DB Name
    if [ -z "$DB_NAME" ]
        then
            printf "${RED}[FAILED]  DB_NAME is empty. ($DB_NAME)\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   DB_NAME:        $DB_NAME${NC}\n";
    fi

    #Build Type
    if [ $BUILD_TYPE != 'jumpstart' ] && [ $BUILD_TYPE != 'divi' ]
        then
            printf "${RED}[FAILED]  BUILD_TYPE can olny be /"jumpstart/" or /"divi/" ($BUILD_TYPE).\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   BUILD_TYPE:         $BUILD_TYPE${NC}\n";
    fi


    #.bashrc
    if [ ! -f "$FILE_BASH" ]
        then
            printf "\n${RED}[FAILED]    FILE_BASH does not exist ($FILE_BASH). This variable must point to your .bashrc file.${NC}\n";
            WPAB_STATUS=false;
        else
            printf "\n${GREEN}[SUCCESS]     FILE_BASH:      $FILE_BASH${NC}\n";
    fi

    #Site files
    if [ ! -d "$PATH_DEV" ]
        then
            printf "${RED}[FAILED]  PATH_DEV does not exist ($PATH_DEV). This variable is the path to the PARENT of your sites' directory.${NC}\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   PATH_DEV:       $PATH_DEV${NC}\n";
    fi

    #check repositories
    if [ -z "${REPO_PATH[$BUILD_TYPE]}" ]
        then
            printf "${RED}[FAILED]  REPO_PATH[$BUILD_TYPE] is empty. This variable should be a reference to the build repository. (${REPO_PATH[$BUILD_TYPE]})${NC}\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   REPO_PATH[$BUILD_TYPE]:     ${REPO_PATH[$BUILD_TYPE]}${NC}\n";
    fi

    #MYSQL Credentials
    if [ -z "$MYSQL_UN" ]
        then
            printf "${RED}[FAILED]  MYSQL_UN is empty ($MYSQL_UN). This variable must be set to a MYSQL Username.\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   MYSQL_UN:       $MYSQL_UN${NC}\n";
    fi

    if [ -z "$MYSQL_PW" ]
        then
            printf "${RED}[FAILED]  MYSQL_PW is empty ($MYSQL_PW). This variable must be set to a MYSQL Password.\n";
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   MYSQL_PW:       $MYSQL_PW${NC}\n";
    fi


    echo ;
    echo ;
    echo "Optional Variables...";
    echo "***********************************";

    #Stop script
    if [ $WPAB_STATUS == false ]
        then
            echo ;
            printf "${RED}Something went wrong. Check the output. Killing process...${NC}\n";
            return 1;
        else
            return 2;
    fi
}

check_CLI_dependencies() {
    WPAB_STATUS=true;

    #check git
    printf "\nChecking git...\n";
    echo "**********************************************";
    if ! [ -x "$(command -v git)" ];
        then
            printf "${RED}[FAILED]  git is NOT accessible.${NC}\n\n" >&2
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   git is accessible.${NC}\n\n";

            #check access to wp-jumpstart
            printf "Checking: Checking access to ${REPO_PATH[$BUILD_TYPE]}\n";
            git ls-remote "${REPO_PATH[$BUILD_TYPE]}" --exit-code;

            # ls-remote returns anything other than 0, then you cannot access
            if [ "$?" -ne 0 ];
                then
                    printf "${RED}[FAILED]  Unable to read from ${REPO_PATH[$BUILD_TYPE]}${NC}\n\n";
                    WPAB_STATUS=false;
                else
                    printf "${GREEN}[SUCCESS]   Access to ${REPO_PATH[$BUILD_TYPE]} is good.${NC}\n\n";
            fi

    fi


    #check mysql
    printf "\nChecking mysql...\n";
    echo "**********************************************";
    if ! [ -x "$(command -v mysql)" ];
        then
            printf "${RED}[FAILED]  mysql is NOT accessible.${NC}\n" >&2;
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   myqsl is accessible.${NC}\n";

            # check_mysql_access returns anything other than 0, then you cannot access
            if [ "$?" -ne 0 ];
                then
                    printf "${RED}[FAILED]  Unable to connect to MYSQL. Either credentials are not valid (UN: $MYSQL_UN PW: $MYSQL_PW) or MYSQL is not running. ${NC}\n\n";
                    WPAB_STATUS=false;
                else
                    printf "${GREEN}[SUCCESS]   Access to MYSQL is good.${NC}\n\n";
            fi
    fi


    #check wp
    printf "\nChecking wp-cli...\n";
    echo "**********************************************";
    if ! [ -x "$(command -v wp)" ];
        then
            printf "${RED}[FAILED]  wp-cli is not installed correctly.${NC}\n" >&2
            WPAB_STATUS=false;
        else
            printf "${GREEN}[SUCCESS]   wp-cli is good.${NC}\n"

    fi

    #Stop script
    if [ $WPAB_STATUS == false ]
        then
            echo ;
            printf "${RED}Something went wrong. Check the output. Killing process...${NC}\n";
            return 1;
        else
            return 2;
    fi
}

#open site url in default browser
open_wpab_site () {
    printf "\n${GREEN}Launching Website...\n";
    printf "*****************************************${NC}\n";
    printf "Opening url in default browser...";
    
    start https://$PROJECT_NAME.somedomain.com
}

标签: linuxshellcommand-line-interface

解决方案


您正在从 CLI 执行脚本,它实际上会生成一个子 shell,运行您的脚本然后终止。当它终止时,所有创建的环境变量和函数都会被丢弃。它们永远不会到达您当前的shell,因此您不能从脚本中定义的 shell 调用函数。

如果要定义当前环境中可用的函数,则需要source定义这些函数的脚本,或者,因为这符合 POSIX,所以使用.. 通常,在定义行为类似于自定义内置命令的函数时,您将函数定义添加到.bashrc或类似的东西,或者您source从那里添加脚本。

我实际上想知道为什么你能打电话给你wp_auto_build一段时间。我假设您通过将脚本从您最喜欢的文本编辑器直接粘贴到 shell 中来测试您的脚本。这确实在您当前的环境中定义了变量和函数。


推荐阅读