programing

매개 변수를 사용하는 Bash 별칭을 만드시겠습니까?

minimums 2023. 6. 7. 22:25
반응형

매개 변수를 사용하는 Bash 별칭을 만드시겠습니까?

저는 매개 변수를 사용하는 별칭을 만들 수 있는 CSshell()을 사용했습니다.그 표기법은 다음과 같았습니다.

alias junk="mv \\!* ~/.Trash"

Bash에서는 이것이 작동하지 않는 것 같습니다.Bash에는 여러 가지 유용한 기능이 있기 때문에 이 기능이 구현되었다고 생각하지만 어떻게 구현되었는지 궁금합니다.

Bash 별칭은 매개 변수를 직접 수락하지 않습니다.함수를 만들어야 합니다.

alias에서는 매개 변수를 허용하지 않지만 별칭처럼 함수를 호출할 수 있습니다.예:

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}


myfunction old.conf new.conf #calls `myfunction`

는 당신의 Bash 능은다에 .bashrc및 기타 파일은 셸 내에서 명령으로 사용할 수 있습니다., 를 이렇게 수 .

$ myfunction original.conf my.conf

위의 답변을 세분화하면 별칭에 대해 얻을 수 있는 것과 같은 한 줄 구문을 얻을 수 있으며, 이는 셸 또는 .bashrc 파일의 임시 정의에 더 편리합니다.

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

오른쪽 괄호를 닫기 전에 세미콜론을 잊지 마세요.마찬가지로, 실제 질문의 경우:

csh% alias junk="mv \\!* ~/.Trash"

bash$ junk() { mv "$@" ~/.Trash/; }

또는:

bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

그 질문은 단순히 잘못된 것입니다.다음과 같은 이유로 매개 변수를 사용하는 별칭을 만들지 않습니다.alias이미 존재하는 항목의 두 번째 이름만 추가합니다.의 기능입니다.function새 함수를 만드는 명령입니다.함수에 이미 이름이 있으므로 해당 함수의 별칭을 지정할 필요가 없습니다.

당신은 다음과 같은 것을 원하는 것 같습니다.

function trash() { mv "$@" ~/.Trash; }

바로 그거야!$1, $2, $3 등의 매개 변수를 사용하거나 $@로 모두 채울 수 있습니다.

TL;DR: 대신 이 작업을 수행합니다.

명령의 중간에 인수를 넣는 별칭보다 함수를 사용하는 것이 훨씬 쉽고 읽기 쉽습니다.

$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after

계속 읽어보면 셸 인수 처리에 대해 알 필요가 없는 것들을 배울 수 있습니다.지식은 위험합니다.어둠이 당신의 운명을 영원히 지배하기 전에 당신이 원하는 결과를 얻으세요.

명확화

bash별칭은 인수를 허용하지만 마지막에만 사용할 수 있습니다.

$ alias speak=echo
$ speak hello world
hello world

다음을 통해 인수를 명령의 중간에 배치alias정말로 가능하지만 점점 더 험악해집니다.

집에서 이런 짓 하지 마, 얘들아!

만약 여러분이 한계를 극복하고 다른 사람들이 불가능하다고 말하는 것을 하는 것을 좋아한다면, 여기 레시피가 있습니다.머리가 헝클어지고 얼굴이 그을린 미치광이 과학자 스타일로 변해도 저를 탓하지 마세요.

해결 방법은 다음과 같은 주장을 전달하는 것입니다.alias에서는 중간에 삽입한 다음 명령을 실행하는 래퍼의 끝 부분만 허용합니다.

솔루션 1

기능 자체를 사용하는 것에 반대하는 경우 다음을 사용할 수 있습니다.

$ alias wrap_args='f(){ echo before "$@" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

▁you▁can있습수를 대체할 수 있습니다.$@와 함께$1당신이 첫 번째 주장만 원한다면요.

설명 1

기능인 면임기생다성니됩능이그를 .f이는 인수를 전달합니다(참고).f맨 끝에 호출됨).unset -f에서는 별칭이 실행될 때 함수 정의를 제거하여 이후에 주변에 남아 있지 않도록 합니다.

솔루션 2

하위 셸을 사용할 수도 있습니다.

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

설명 2

별칭은 다음과 같은 명령을 작성합니다.

sh -c 'echo before "$@" after' _

댓글:

  • 표시자 자리시_필요하지만, 무엇이든 될 수 있습니다.으로 설다니됩정으로 됩니다.sh$0사용자가 지정한 첫 번째 인수가 사용되지 않도록 하기 위해 필요합니다.시연:

    sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
    Consumed: alcohol Printing: drunken babble
    
  • 단일 따옴표 안에 있는 단일 따옴표가 필요합니다.다음은 큰따옴표를 사용하지 않는 예입니다.

    $ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
    Consumed: -bash Printing:
    

    의 여기서셸의의 은 다음과 .$0그리고.$@로 전달되기 전에 이중 따옴표로 대체됩니다.sh증거는 다음과 같습니다.

    echo "Consumed: $0 Printing: $@"
    Consumed: -bash Printing:
    

    단일 따옴표는 이러한 변수가 대화형 셸에 의해 해석되지 않고 문자 그대로 다음으로 전달되도록 합니다.sh -c.

    와 두개인를사수있고용할구용의▁double,,\$@ 좋은 주장을 (공백이 될 수도 있기 에) "고맙다"는 것입니다.\"\$@\"훨씬 더 못생기게 보이지만, 프래즐 머리가 참가의 전제 조건인 난독화 대회에서 우승하는 데 도움이 될 수 있습니다.

별칭 내부에 함수를 만들기만 하면 됩니다.

$ alias mkcd='_mkcd(){ mkdir "$1"; cd "$1";}; _mkcd'
             ^        *      ^  ^     ^  ^         ^

큰따옴표는 "$1"로 묶어야 합니다. 작은따옴표는 사용할 수 없기 때문입니다.화살표로 표시된 위치에서 따옴표를 충돌하면 시스템이 혼란스러워지기 때문입니다.또한 기능을 위해서는 별이 표시된 곳의 공간이 필요합니다.

한번은 재미있는 프로젝트를 했고 지금도 사용하고 있습니다.다음을 통해 파일을 복사하는 동안 일부 애니메이션이 표시됩니다.cp coz 령명z cozcp아무것도 보여주지 않고 좀 답답합니다.그래서 제가 만든 별명은cp:

alias cp="~/SCR/spinner cp"

그리고 이것은 스피너 대본입니다.

#!/bin/bash

#Set timer
T=$(date +%s)

#Add some color
. ~/SCR/color

#Animation sprites
sprite=( "(* )  ( *)" " (* )( *) " " ( *)(* ) " "( *)  (* )" "(* )  ( *)" )

#Print empty line and hide cursor
printf "\n${COF}"

#Exit function
function bye { printf "${CON}"; [ -e /proc/$pid ] && kill -9 $pid; exit; }; trap bye INT

#Run our command and get its pid
"$@" & pid=$!

#Waiting animation
i=0; while [ -e /proc/$pid ]; do sleep 0.1

    printf "\r${GRN}Please wait... ${YLW}${sprite[$i]}${DEF}"
    ((i++)); [[ $i = ${#sprite[@]} ]] && i=0

done

#Print time and exit
T=$(($(date +%s)-$T))
printf "\n\nTime taken: $(date -u -d @${T} +'%T')\n"

bye

이렇게 생겼어요.

여기에 이미지 설명 입력

애니메이션 주기)

여기에 이미지 설명 입력

위에 언급된 컬러 스크립트에 대한 링크입니다.그리고 새로운 애니메이션 주기)

여기에 이미지 설명 입력

그래서 OP의 질문에 대한 답은 원하는 대로 Arg를 섞을 수 있는 중간 스크립트를 사용하는 것입니다.

다른 해결책은 명령 템플릿을 "북마크"하고 명령 자리 표시자에 커서를 쉽게 배치할 수 있는 최근에 만든 도구인 마커를 사용하는 것입니다.

명령줄 마커

저는 대부분 셸 기능을 사용하기 때문에 자주 사용하는 명령어를 명령줄에 반복해서 쓸 필요가 없다는 것을 알게 되었습니다.이 사용 사례에서 함수를 사용하는 문제는 명령어 어휘에 새 용어를 추가하고 실제 명령에서 어떤 함수 매개 변수를 참조하는지 기억해야 한다는 것입니다.마커 목표는 그 정신적 부담을 없애는 것입니다.

구문:

alias shortName="your custom command here"

예:

alias tlogs='_t_logs() { tail -f ../path/$1/to/project/logs.txt ;}; _t_logs'

Bash 별칭은 매개 변수를 절대적으로 허용합니다.저는 앱 이름을 매개 변수로 받아들이는 새로운 리액트 앱을 만들기 위해 별칭을 추가했습니다.제 프로세스는 다음과 같습니다.

nano에서 편집할 bash_profile 열기

nano /.bash_profile

한 줄에 하나씩 별칭을 추가합니다.

alias gita='git add .'
alias gitc='git commit -m "$@"'
alias gitpom='git push origin master'
alias creact='npx create-react-app "$@"'

참고: "$@"는 "creact my-new-app"과 같이 전달된 매개 변수를 수락합니다.

nano 편집기 저장 및 종료

ctrl+o를 눌러 기록하고( Enter 키를 눌러), ctrl+x를 눌러 종료합니다.

터미널에 .bash_profile의 새 별칭을 사용하도록 지시

source /.bash_profile

바로 그거야!이제 새 별칭을 사용할 수 있습니다.

다음은 제가 가진 기능의 세 가지 예입니다.~/.bashrc기본적으로 매개 변수를 허용하는 별칭입니다.

#Utility required by all below functions.
#https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"

.

:<<COMMENT
    Alias function for recursive deletion, with are-you-sure prompt.

    Example:
        srf /home/myusername/django_files/rest_tutorial/rest_venv/

    Parameter is required, and must be at least one non-whitespace character.

    Short description: Stored in SRF_DESC

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*rm -r*:srf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - y/n prompt: https://stackoverflow.com/a/3232082/2736496
    - Alias w/param: https://stackoverflow.com/a/7131683/2736496
COMMENT
#SRF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
SRF_DESC="srf [path]: Recursive deletion, with y/n prompt\n"
srf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    #Actual line-breaks required in order to expand the variable.
    #- https://stackoverflow.com/a/4296147/2736496
    read -r -p "About to
    sudo rm -rf \"$param\"
Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        sudo rm -rf "$param"
    else
        echo "Cancelled."
    fi
}

.

:<<COMMENT
    Delete item from history based on its line number. No prompt.

    Short description: Stored in HX_DESC

    Examples
        hx 112
        hx 3

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HX_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HX_DESC="hx [linenum]: Delete history item at line number\n"
hx()  {
    history -d "$1"
}

.

:<<COMMENT
    Deletes all lines from the history that match a search string, with a
    prompt. The history file is then reloaded into memory.

    Short description: Stored in HXF_DESC

    Examples
        hxf "rm -rf"
        hxf ^source

    Parameter is required, and must be at least one non-whitespace character.

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*hxf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HXF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HXF_DESC="hxf [searchterm]: Delete all history items matching search term, with y/n prompt\n"
hxf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    read -r -p "About to delete all items from history that match \"$param\". Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        #Delete all matched items from the file, and duplicate it to a temp
        #location.
        grep -v "$param" "$HISTFILE" > /tmp/history

        #Clear all items in the current sessions history (in memory). This
        #empties out $HISTFILE.
        history -c

        #Overwrite the actual history file with the temp one.
        mv /tmp/history "$HISTFILE"

        #Now reload it.
        history -r "$HISTFILE"     #Alternative: exec bash
    else
        echo "Cancelled."
    fi
}

참조:

별칭 중간에 매개 변수를 삽입할 수 없다고 말하는 모든 사람들에게 정중하게 말씀드리지만, 방금 테스트를 해보니 제대로 작동했습니다.

alias mycommand = "python3 "$1" script.py --folderoutput RESULTS/"

그리고 나서 제가 명령어 푸바를 실행했을 때, 마치 제가 명령어를 길게 입력한 것으로 입력한 것처럼 정확히 작동했습니다.

NB: 아이디어가 명확하지 않은 경우, 별칭을 제외한 모든 항목에 별칭을 사용하는 것은 좋지 않습니다. 첫 번째는 '에일리어스의 함수'이고 두 번째는 '리다이렉트/소스를 읽기 어렵습니다'입니다.또한 결함이 있습니다(분명할 것이라고 생각했지만, 만약 당신이 혼란스러울 경우를 대비하여:실제로 사용하려는 것이 아닙니다.어디든!)


이전에도 답변을 드렸는데, 과거에도 항상 그러했습니다.

alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'

기능의 사용을 모두 피하는 것이 아니라면, 그것은 괜찮고 좋습니다.이 경우 Bash의 광범위한 텍스트 리디렉션 기능을 활용할 수 있습니다.

alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'

두 문자 모두 길이가 거의 같습니다.

진정한 키커는 시차인데, 상단은 '함수 방식'이고 하단은 '리다이렉트 소스' 방식입니다.이 이론을 증명하기 위해, 시기는 다음과 같이 설명합니다.

arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.004s sys 0m0.008s  # <--time spent in foo
 real 0m0.000s user 0m0.000s sys 0m0.000s  # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.000s sys 0m0.012s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.012s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.008s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE

이것은 무작위 간격으로 수행된 약 200개의 결과의 하단 부분입니다.기능 생성/파괴는 리디렉션보다 시간이 더 많이 소요되는 것으로 보입니다.이것이 이 질문에 대한 미래의 방문자들에게 도움이 되기를 바랍니다(나만 알고 싶지 않았습니다).

하나 또는 두 개 또는 다른 하드 코딩된 양이 아닌 모든 매개 변수를 함수에 적용하는 일반적인 방법을 찾고 있는 경우 다음과 같은 방법을 사용할 수 있습니다.

#!/usr/bin/env bash

# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
    java -jar myjar.jar "$@";
}

alias runjar=runjar_fn;

에서, 가 그서위의예에서, 실때모부매든변전개다달니수합를을 실행할 합니다.runjar가명으로

예를 들어, 만약 내가 그랬다면,runjar hi there실제로 실행될 것입니다.java -jar myjar.jar hi there만약 그랬다면,runjar one two three그것은 실행될 것입니다.java -jar myjar.jar one two three.

난 이것이 좋다.$@여러 개의 매개 변수와 함께 작동하기 때문에 기반 솔루션을 선택할 수 있습니다.

Bash 별칭이 임의 인수의 위치를 변경할 수 있는 메커니즘을 가지고 있지 않은 문제에 대한 일반화된 해결책을 원하는 정당한 기술적 이유가 있습니다.한 가지 이유는 실행하려는 명령이 기능 실행으로 인해 발생하는 환경 변화에 의해 부정적인 영향을 받을 수 있기 때문입니다.다른 모든 경우에는 기능을 사용해야 합니다.

최근에 제가 이것에 대한 해결책을 시도하게 된 이유는 변수와 함수의 정의를 인쇄하기 위한 몇 가지 간략화된 명령을 만들고 싶었기 때문입니다.그래서 저는 그 목적을 위해 몇 가지 기능을 썼습니다.그러나 함수 호출 자체에 의해 변경되거나 변경될 수 있는 특정 변수가 있습니다.그 중에는 다음이 포함됩니다.

FUNCNAME BASH_SOURC BASH_LINENO BASH_ARGC BASH_ARGV

변수 정의를 인쇄하기 위해 (함수에서) 사용했던 기본 명령입니다.set 명령에 의해 출력되는 형식은 다음과 같습니다.

sv () { set | grep --color=never -- "^$1=.*"; }

예:

> V=voodoo
sv V
V=voodoo

문제:이렇게 하면 위에서 언급한 변수의 정의가 현재 컨텍스트에 있는 것처럼 인쇄되지 않습니다. 예를 들어 대화형 셸 프롬프트에서(또는 함수 호출에서) FUNCNAME이 정의되지 않은 경우입니다.하지만 제 기능이 잘못된 정보를 알려줍니다.

> sv FUNCNAME
FUNCNAME=([0]="sv")

제가 생각해 낸 한 가지 해결책은 이 주제에 대한 다른 게시물에서 다른 사람들에 의해 언급되었습니다.변수 정의를 인쇄하는 이 특정 명령에 대해 다음과 같이 수행했습니다. 이 명령에는 인수가 하나만 필요합니다.

alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'

그러면 올바른 출력(없음)과 결과 상태(거짓)가 표시됩니다.

> asv FUNCNAME
> echo $?
1

하지만, 저는 여전히 임의의 수의 논쟁에 효과적인 해결책을 찾아야 한다고 느꼈습니다.

Bash 별칭 명령에 임의 인수 전달에 대한 일반 솔루션:

# (I put this code in a file "alias-arg.sh"):

# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }

# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
    # Set up cmd to be execed after f() finishes:
    #
    trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
    #        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #       (^This is the actually execed command^)
    #
    # f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
    f () {
        declare -ag CMD_ARGV=("$@");  # array to give args to cmd
        kill -SIGUSR1 $$;             # this causes cmd to be run
        trap SIGUSR1;                 # unset the trap for SIGUSR1
        unset CMD_ARGV;               # clean up env...
        unset f;                      # incl. this function!
    };
    f'  # Finally, exec f, which will receive the args following "ac2".

예:

> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true

이 솔루션의 좋은 점은 트랩된 명령을 구성할 때 명령에 대한 위치 매개 변수(인수)를 처리하는 데 사용되는 모든 특수 트릭이 작동한다는 것입니다.유일한 차이점은 배열 구문을 사용해야 한다는 것입니다.

예.,

"$@"를 원하는 경우 "${CMD_ARGV[@]}"를 사용합니다.

"$#"을(를) 원할 경우 "${#CMD_ARGV[@]}"을(를) 사용합니다.

기타.

저는 제 (희망적으로, 좋아요) 해결책을 (미래 독자들을 위해, 그리고 가장 중요한; 편집자들을 위해) 게시할 것입니다.
따라서 - 이 게시물의 내용을 편집 및 개선/제거해 주시기 바랍니다.

터미널:

$ alias <name_of_your_alias>_$argname="<command> $argname"

사용하려면('_' 뒤에 공백 표시):

$<name_of_your_alias>_ $argname

를 들어, 예들어, 에대별칭의 입니다.cathello.txt:

  • 은 ( )입니다.CAT_FILE_)
  • 리고그고.$f는 (아래),$argname입니다).
$ alias CAT_FILE_$f="cat $f"

$ echo " " >> hello.txt
$ echo "hello there!" >> hello.txt
$ echo " " >> hello.txt
$ cat hello.txt

    hello there!

테스트('_' 뒤에 공백이 있음에 유의):

CAT_FILE_ hello.txt

다른 사람들이 이미 지적했듯이, 기능을 사용하는 것은 모범 사례로 간주되어야 합니다.

그러나, 여기에는 다음과 같은 다른 접근 방식이 있습니다.xargs:

alias junk="xargs -I "{}" -- mv "{}" "~/.Trash" <<< "

스트림 리디렉션과 관련하여 부작용이 있습니다.

하위 명령을 사용하는 솔루션:

d () {
    if [ $# -eq 0 ] ; then
        docker
        return 0
    fi
    CMD=$1
    shift

    case $CMD in
    p)
        docker ps --all $@
        ;;
    r)
        docker run --interactive --tty $@
        ;;
    rma)
        docker container prune
        docker image prune --filter "dangling=true"
        ;;
    *)
        docker $CMD $@
        ;;
    esac
    return $?
}

사용:

$ d r my_image ...

호출:

docker run --interactive --tty my_image ...

다음은 예입니다.

alias gcommit='function _f() { git add -A; git commit -m "$1"; } ; _f'

매우 중요:

  1. 뒤에 이 있습니다.{ 그이에 앞에}.
  2. 이 .;각 명령 뒤에 순서대로 표시됩니다.마지막 명령 뒤에 이 명령을 잊어버린 경우 다음과 같이 표시됩니다.>대신 프롬프트!
  3. 인수는 다음과 같이 따옴표로 묶습니다."$1"

파일을 삭제하는 대신 휴지통 폴더로 이동하는 별칭을 만드는 것에 대해 제기된 질문에 구체적인 답변을 제공하려면 다음을 수행합니다.

alias rm="mv "$1" -t ~/.Trash/"

당연히 dir ~/를 생성해야 합니다.쓰레기 먼저.

그런 다음 다음 명령을 내립니다.

$rm <filename>
$rm <dirname>

다음은 다음을 사용하는 또 다른 접근 방식입니다.read"권한 거부" 메시지를 무시하고 이름 조각별로 파일을 브루트 검색하는 데 사용합니다.

alias loc0='( IFS= read -r x; find . -iname "*" -print 2>/dev/null | grep $x;) <<<'

간단한 예:

$ ( IFS= read -r x; echo "1 $x 2 ";) <<< "a b"
1 a b 2 

이렇게 하면 인수가 문자열로 변환되어 변수로 변환됩니다.따옴표 안에 공백으로 구분된 여러 매개 변수를 사용할 수 있습니다.

$ ( read -r x0 x1; echo "1 ${x0} 2 ${x1} 3 ";) <<< "a b"
1 a 2 b 3 

함수는 실제로 거의 항상 이미 충분히 기여하고 맨 페이지의 이 인용문에 의해 확인된입니다. "거의 모든 목적에서 별칭은 셸 함수로 대체됩니다."

완전성을 위해 그리고 이것이 유용할 수 있기 때문에(약간 더 가벼운 구문) 매개 변수가 별칭을 따를 때 여전히 사용될 수 있다는 것에 주목할 수 있습니다(OP의 요구 사항을 다루지는 않겠지만).이를 예로 들어 설명하는 것이 가장 쉬울 것입니다.

alias ssh_disc='ssh -O stop'

를 smth처럼 할 수 .ssh_disc myhost확장됩니다.ssh -O stop myhost

이는 복잡한 인수를 사용하는 명령에 유용할 수 있습니다(내 메모리는 더 이상 예전의 메모리가 아닙니다...).

매개 변수를 사용하려면 함수를 사용해야 합니다!

하지만 $@는 별칭을 실행하는 동안이 아니라 별칭을 생성할 때 해석되며 $를 이스케이프하는 것도 작동하지 않습니다.이 문제를 어떻게 해결해야 합니까?

이 문제를 제거하려면 별칭 대신 셸 기능을 사용해야 합니다.foo는 다음과 같이 정의할 수 있습니다.

function foo() { /path/to/command "$@" ;}

OR

foo() { /path/to/command "$@" ;}

마지막으로 다음 구문을 사용하여 foo()를 호출합니다.

foo arg1 arg2 argN

를 foo()에 .~/.bash_profile또는~/.zshrcjava.

당신의 경우, 이것은 효과가 있을 것입니다.

function trash() { mv $@ ~/.Trash; }

함수와 별칭 모두 다른 사용자가 여기에 표시한 것처럼 매개 변수를 사용할 수 있습니다.추가로, 저는 다음과 같은 두 가지 측면을 지적하고 싶습니다.

함수가 자체 범위에서 실행됨, 별칭 공유 범위

무언가를 숨기거나 노출해야 할 경우 이 차이를 아는 것이 유용할 수 있습니다.또한 캡슐화를 위해 함수가 더 나은 선택임을 시사합니다.

function tfunc(){
    GlobalFromFunc="Global From Func" # Function set global variable by default
    local FromFunc="onetwothree from func" # Set a local variable

}

alias talias='local LocalFromAlias="Local from Alias";  GlobalFromAlias="Global From Alias" # Cant hide a variable with local here '
# Test variables set by tfunc
tfunc # call tfunc
echo $GlobalFromFunc # This is visible
echo $LocalFromFunc # This is not visible
# Test variables set by talias
# call talias
talias
echo $GlobalFromAlias # This is invisible
echo $LocalFromAlias # This variable is unset and unusable 

출력:

bash-3.2$     # Test variables set by tfunc
bash-3.2$     tfunc # call tfunc
bash-3.2$     echo $GlobalFromFunc # This is visible
Global From Func
bash-3.2$     echo $LocalFromFunc # This is not visible

bash-3.2$     # Test variables set by talias
bash-3.2$     # call talias
bash-3.2$     talias
bash: local: can only be used in a function
bash-3.2$     echo $GlobalFromAlias # This is invisible
Global From Alias
bash-3.2$ echo $LocalFromAlias # This variable is unset and unusable

래퍼 스크립트가 더 나은 선택입니다.

사용자 이름 또는 다중 사용자 환경 전환을 통해 로그인하거나 로그인할 때 별칭 또는 함수를 찾을 수 없는 경우가 여러 번 있었습니다.도트 파일을 소싱하는 데 필요한 팁과 요령 또는 별칭이 있는 흥미로운 팁이 있습니다.alias sd='sudo ' 별칭인 이속후별허니다합용을칭▁this다니▁lets를 사용할 수 있습니다.alias install='sd apt-get install'sd='sudo ' 이런더 잘 하지만 이런 경우에는 함수나 별칭보다 래퍼 스크립트가 더 잘 작동합니다.래퍼 스크립트의 주요 장점은 의도된 경로(예: /usr/loca/bin/)에 대해 표시/실행 가능하다는 것이며 함수/에일리어스는 사용하기 전에 소스되어야 합니다.들어 또는 하면 ~/.bash_profile이 ~/.bashrc가 .bash 셸 그나나다즉셸전로다니환합른에중러즉(다▁(,▁to니▁but,zsh그러면 기능이 더 이상 표시되지 않습니다.따라서 의심스러울 때는 포장지 스크립트가 항상 가장 안정적이고 휴대하기 쉬운 솔루션입니다.

alias junk="delay-arguments mv _ ~/.Trash"

delay-arguments스크립트:

#!/bin/bash

# Example:
# > delay-arguments echo 1 _ 3 4 2
# 1 2 3 4
# > delay-arguments echo "| o n e" _ "| t h r e e" "| f o u r" "| t w o"
# | o n e | t w o | t h r e e | f o u r

RAW_ARGS=("$@")

ARGS=()

ARG_DELAY_MARKER="_"
SKIPPED_ARGS=0
SKIPPED_ARG_NUM=0
RAW_ARGS_COUNT="$#"

for ARG in "$@"; do
  #echo $ARG
  if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
    SKIPPED_ARGS=$((SKIPPED_ARGS+1))
  fi
done

for ((I=0; I<$RAW_ARGS_COUNT-$SKIPPED_ARGS; I++)); do
  ARG="${RAW_ARGS[$I]}"
  if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
    MOVE_SOURCE_ARG_NUM=$(($RAW_ARGS_COUNT-$SKIPPED_ARGS+$SKIPPED_ARG_NUM))
    MOVING_ARG="${RAW_ARGS[$MOVE_SOURCE_ARG_NUM]}"
    if [[ "$MOVING_ARG" == "$ARG_DELAY_MARKER" ]]; then
      echo "Error: Not enough arguments!"
      exit 1;
    fi
    #echo "Moving arg: $MOVING_ARG"
    ARGS+=("$MOVING_ARG")
    SKIPPED_ARG_NUM=$(($SKIPPED_ARG_NUM+1))
  else
    ARGS+=("$ARG")
  fi
done

#for ARG in "${ARGS[@]}"; do
  #echo "ARGN: $ARG"
#done

#echo "RAW_ARGS_COUNT: $RAW_ARGS_COUNT"
#echo "SKIPPED_ARGS: $SKIPPED_ARGS"

#echo "${ARGS[@]}"
QUOTED_ARGS=$(printf ' %q' "${ARGS[@]}")
eval "${QUOTED_ARGS[@]}"

언급URL : https://stackoverflow.com/questions/7131670/make-a-bash-alias-that-takes-a-parameter

반응형