Fish에서 bash 별칭에 액세스하는 방법

Fish에서 bash 별칭에 액세스하는 방법

Fish에 bash 별칭이 누락되어 수동으로 모두 Fish 함수로 변환하고 싶지 않습니다. 물고기에게서 이 모든 것을 어떻게 얻나요?

다음과 같은 경우 보너스 포인트:

  • 이 솔루션은 다음과 같은 반복 프로세스를 지원합니다. bash에서 별칭을 쉽게 변경하고 이를 Fish로 다시 변환/다시 가져올 수 있습니다.
  • 이 솔루션은 bash 기능도 가져옵니다.

답변1

나는 이 기사를 우연히 발견했습니다. 첫 번째 스크립트는 매우 훌륭하지만 모든 별칭에 대해 하나의 파일을 사용하고 싶습니다. 또 다른 간단하고 간결한 방법은 다음과 같습니다.

모든 별칭을 이동한 ~/.bash_aliases다음
이 줄을 추가하세요.~/.config/fish/config.fish

source ~/.bash_aliases

답변2

bash 별칭을 bash 스크립트로 변환

나는 아래 방법을 사용하는 대신 이 작업을 수행하기로 결정하고 스크립트를 ~/bin/PATH작업에 넣었습니다.모든 쉘에서 사용, 잠재적인 참조 문제를 방지합니다. 그것재귀 별칭 건너뛰기처럼 alias ls='ls -la', 스크립트로 사용할 때 무한 재귀가 발생하기 때문입니다! 해결 방법으로 별칭에 절대 경로를 사용하세요 alias ls='/bin/ls -la'.

용법

# converts all bash aliases to script files
convert_bash_aliases_to_scripts

# removes all scripts previously converted by this script
convert_bash_aliases_to_scripts clean

스크립트

#!/bin/bash
# Convert bash aliases to bash scripts.
#
# Copyright 2018 <[email protected]>, licensed under the GPL-3.0+
#
# Usage:
#   convert_bash_aliases_to_scripts          # converts all bash aliases to script files
#   convert_bash_aliases_to_scripts clean    # removes all scripts previously converted by this script

COLOR_RED=$'\e[0;31m'
COLOR_ORANGE=$'\e[0;33m'
COLOR_BLUE=$'\e[0;34m'
COLOR_BLUE_LIGHT=$'\e[1;34m'
COLOR_GREEN=$'\e[0;32m'
COLOR_BROWN=$'\e[0;33m'
COLOR_YELLOW=$'\e[1;33m'
COLOR_WHITE=$'\e[1;37m'
COLOR_CYAN=$'\e[0;36m'
COLOR_PURPLE=$'\e[0;35m'
COLOR_GRAY=$'\e[1;30m'
COLOR_GRAY_LIGHT=$'\e[0;37m'
COLOR_NONE=$'\e[m' # No Color

OUTPUT_DIR=~/bin/converted/aliases
LINKS_DIR=~/bin
README_FILE_NAME="README.md"
README_FILE="$OUTPUT_DIR/$README_FILE_NAME"

if [ "$1" = "clean" ]
then
    for script_file in $(find "$LINKS_DIR" -maxdepth 1 -type l)
    do
        conv_script_file="$OUTPUT_DIR/$(basename $script_file)"
        if [ -e $conv_script_file ] && [ "$(readlink --canonicalize $script_file)" = "$(realpath $conv_script_file)" ]
        then
            script_name=$(basename $script_file)
            echo "removing converted bash alias-script: $script_name"
            rm $conv_script_file \
                && rm $script_file
        fi
    done
    rm $README_FILE 2> /dev/null
    rmdir $OUTPUT_DIR 2> /dev/null
    exit 0
fi

SOURCE_FILES="${HOME}/.bashrc ${HOME}/.bash_aliases"
mkdir -p $OUTPUT_DIR
echo -e "# Bash alias conversion scripts\n\nsee $0\n\nWARNING: Do NOT manually edit files in this directory. instead, copy them to $LINKS_DIR (replacing the symbolic link that already exists there), and edit that new file.\nIf you edit the files in this dir, it will be replaced on the next (re)conversion from aliases." \
    > $README_FILE
AUTO_IMPORT_WARNING="# WARNING Do NOT edit this file by hand, as it was auto-generated from a bash alias, and may be overwritten in the future. please read ${README_FILE}"

function _is_link_to {
    local file_link=$1
    local file_target=$2
    test -e $file_target \
        && test "$(readlink --canonicalize $file_link)" = "$(realpath $file_target)"
    return $?
}

function _is_recursive_alias () {
    local alias_name="$1"
    local alias_command="$2"
    local alias_command_first_word=$(echo "$alias_command" | sed -e 's/^[ \t]*['\''\"]\?//' -e 's/[ \t].*//')
    test "$alias_command_first_word" = "$alias_name"
    return $?
}

for source_file in $SOURCE_FILES
do
    IFS=$'\n'
    for a in $(cat $source_file | grep "^alias")
    do
        a_name="$(echo "$a" | sed -e 's/alias \([^=]*\)=.*/\1/')"
        a_command="$(echo "$a" | sed -e 's/alias \([^=]*\)=//' -e 's/[ \t]*#.*$//')"
        if echo "${a_command:0:1}" | grep -q -e "[\'\"]"
        then
            # unquote
            a_command_start=1
            let a_command_end="${#a_command} - 2"
        else
            # leave as is
            a_command_start=0
            let a_command_end="${#a_command}"
        fi
        script_file="$LINKS_DIR/$a_name"
        conv_script_file="$OUTPUT_DIR/$a_name"
        # Check whether the script already exists.
        # If so, we skip importing it, unless it is just a link to a previously imported script.
        log_action="ignored"
        log_action_color="${COLOR_NONE}"
        log_content=""
        if [ -e $script_file ] && ! $(_is_link_to $script_file $conv_script_file)
        then
            log_action="skipped (exists)"
            log_action_color="${COLOR_ORANGE}"
        elif _is_recursive_alias "$a_name" "$a_command"
        then
            log_action="skipped (recursive)"
            log_action_color="${COLOR_RED}"
        else
            if [ -e $script_file ]
            then
                log_action="reimporting"
                log_action_color="${COLOR_BLUE}"
            else
                log_action="importing"
                log_action_color="${COLOR_GREN}"
            fi

            # write the script file to a temporary location
            conv_script_file_tmp="${conv_script_file}_BAK"
            echo "#!/bin/bash" > $conv_script_file_tmp
            echo -e "$AUTO_IMPORT_WARNING" >> $conv_script_file_tmp
            echo -e "#\n# Imported bash alias '$a_name' from file '$source_file'" >> $conv_script_file_tmp
            cat >> "${conv_script_file_tmp}" <<EOF

${a_command:${a_command_start}:${a_command_end}} \${@}

EOF

            if diff -N ${conv_script_file_tmp} ${conv_script_file} > /dev/null
            then
                log_content="no change"
                log_content_color="${COLOR_NONE}"
            else
                log_content="changed"
                log_content_color="${COLOR_GREEN}"
            fi
            log_content=$(printf "%s %10s -> %s${COLOR_NONE}" "${log_content_color}" "${log_content}" "$a_command")

            mv "${conv_script_file_tmp}" "${conv_script_file}"

            # make the script executable
            chmod +x $conv_script_file
            # remove the link if it already exists (in case of reimport)
            rm $script_file 2> /dev/null
            # .. and re-create it as local symbolic link
            # to the function in the imports dir
            ln --symbolic --relative $conv_script_file $script_file
        fi
        printf "%s%20s: %-25s${COLOR_NONE}%s\n" "${log_action_color}" "${log_action}" "$a_name" "${log_content}"
    done
done

더 이상 사용되지 않음:Bash 코드를 실행하는 피쉬 래퍼 만들기

다음은 로컬 bash 별칭에 대한 Fish 스크립트 래퍼를 생성하는 스크립트입니다. 각 bash 별칭에 대해 콘텐츠를 가져와 bash 하위 쉘에서 코드를 실행하는 Fish 별칭/스크립트를 생성합니다. 최적은 아니지만 대부분의 별칭에는 충분합니다.

경고하다가져온 함수는 bash와 다르게 동작할 수 있습니다. 이를 사용하면 데이터가 손실되거나 실수로 동료에게 DDoS가 발생할 수 있습니다.

사용법(지원 중단됨)

# imports (or reimports) all bash aliases into fish functions, permanently
import_bash_aliases

# removes all fish functions previously imported by this script
import_bash_aliases clean

스크립트(더 이상 사용되지 않음)

다음 위치에 저장하세요 ~/.config/fish/functions/import_bash_aliases.fish.

#!/usr/bin/fish
# Fish function to import bash aliases
#
# Copyright 2018 <[email protected]>, licensed under the GPL-3.0+
#
# This script is based on a script from Malte Biermann,
# see: https://glot.io/snippets/efh1c4aec0
#
# WARNING: There is no guarantee that the imported aliases work the same way
#   as they do in bash, so be cautious!
#
# Usage:
#   import_bash_aliases          # imports (or reimports) all bash aliases into fish functions, permanently
#   import_bash_aliases clean    # removes all fish functions previously imported by this script from bash aliases

function import_bash_aliases --description 'Converts bash aliases to .fish functions.\nThis might be called repeatedly, and will not override functions that are already defined in fish, except they are merely an older import from this script.'

    set -l FISH_FUNCTIONS_DIR ~/.config/fish/functions
    set -l BASH_IMPORTS_DIR_NAME bash-imports
    set -l BASH_IMPORTS_DIR $FISH_FUNCTIONS_DIR/$BASH_IMPORTS_DIR_NAME
    set -l README_FILE $BASH_IMPORTS_DIR/README.md

    if test "$argv[1]" = "clean"
        for fun_file in (find $FISH_FUNCTIONS_DIR -maxdepth 1 -name '*.fish')
            set -l imp_fun_file $BASH_IMPORTS_DIR/(basename $fun_file)
            if test -e $imp_fun_file ; and test (readlink --canonicalize $fun_file) = (realpath $imp_fun_file)
                set -l fun_name (basename $fun_file '.fish')
                echo "removing imported bash alias/function $fun_name"
                rm $imp_fun_file
                and rm $fun_file
                and functions --erase $fun_name
            end
        end
        rm $README_FILE ^ /dev/null
        rmdir $BASH_IMPORTS_DIR ^ /dev/null
        return 0
    end

    set -l SOURCE_FILES ~/.bashrc ~/.bash_aliases
    mkdir -p $BASH_IMPORTS_DIR
    echo -e "# Bash alias imports\n\nsee `$argv[0]`\n\nWARNING: Do NOT manually edit files in this directory. instead, copy them to $FISH_FUNCTIONS_DIR (replacing the symbolic link that already exists there), and edit that new file.\nIf you edit the files in this dir, it will be replaced on the next (re)import from bash aliases." \
        > $README_FILE
    set -l UNUSED_STUB_MSG "The bash alias corresponding to this function was NOT imported, because a corresponding function already exists at %s\n"
    set -l AUTO_IMPORT_WARNING "# WARNING Do NOT edit this file by hand, as it was auto-generated from a bash alias, and may be overwritten in the future. please read {$README_FILE}"

    function _fish_func_exists
        set -l fun_name $argv[1]
        # This also detects in-memory functions
        functions --query $fun_name
        # This also detects script files in the functions dir
        # that do not contain a function wiht the same name
        or test -e "$FISH_FUNCTIONS_DIR/$fun_name.fish"
        return $status
    end
    function _is_link_to
        set -l file_link $argv[1]
        set -l file_target $argv[2]
        test -e $file_target
        and test (readlink --canonicalize $file_link) = (realpath $file_target)
        return $status
    end

    for source_file in $SOURCE_FILES
        for a in (cat $source_file | grep "^alias")
            set -l a_name (echo $a | sed -e 's/alias \([^=]*\)=.*/\1/')
            set -l a_command (echo $a | sed -e 's/alias \([^=]*\)=//' -e 's/[ \t]*#[^\'\"]\+$//')
            set -l fun_file "$FISH_FUNCTIONS_DIR/$a_name.fish"
            set -l imp_fun_file "$BASH_IMPORTS_DIR/$a_name.fish"
            # Check whether the function already exists.
            # If so, we skip importing it, unless it is just a link to a previously imported function.
            if _fish_func_exists $a_name; and not _is_link_to $fun_file $imp_fun_file
                set_color red
                printf "%20s: %-25s\n" "skipping (exists)" $a_name
                set_color normal
                #printf $UNUSED_STUB_MSG $fun_file > $imp_fun_file
            else
                set_color green
                printf "%20s: %-25s -> %s\n" "(re-)importing" $a_name $a_command
                set_color normal
                # remove the link, in case of re-importing
                rm $fun_file ^ /dev/null

                # write the function file
                echo "#!/usr/bin/fish" > $imp_fun_file
                echo "\
$AUTO_IMPORT_WARNING

function $a_name -d 'bash alias "$a_name" import'
    bash -c $a_command' '\$argv''
end
" \
                    >> $imp_fun_file

                # make the script executable
                chmod +x $imp_fun_file
                # .. and re-create it as local symbolic link
                # to the function in the imports dir
                ln --symbolic --relative $imp_fun_file $fun_file
            end
        end
    end
    # (re-)load all the functions we just defined
    exec fish
end

답변3

다음은 bash 별칭을 Fish로 가져오기 위한 더 간단한 스크립트입니다. 폴더 아래에 다음 내용으로 fish_import_bash_aliases.fish파일을 만듭니다 .~/.config/fish/functions

function fish_import_bash_aliases \
    --description 'import bash aliases to .fish function files.'
    for a in (cat ~/.bash_aliases  | grep "^alias")
        set aname (echo $a | sed 's/alias \(.*\)=\(\'\|\"\).*/\1/')
        set command (echo $a | sed 's/alias \(.*\)=\(\'\|\"\)\(.*\)\2/\3/')
        if test -f ~/.config/fish/functions/$aname.fish
            echo "Overwriting alias $aname as $command"
        else
            echo "Creating alias $aname as $command"
        end
        alias $aname $command
        funcsave $aname
    end
end

스크립트 파일이 준비되면 fish_import_bash_aliasesFish 셸에서 실행하세요. 이렇게 하면 아래의 각 bash 별칭에 대한 Fish 함수 스크립트가 생성됩니다 ~/.config/fish/functions.

관련 정보