본문 바로가기
리눅스

Fish (Unix shell)

by 다움위키 2025. 4. 2.

원문 보기: https://dawoum.duckdns.org/wiki/Fish_(Unix_shell)

 

Original article: w:Fish (Unix shell)

 

Fish (또는 friendly interactive shell- 소문자로 양식화됨)는 상호 작용과 유용성에 중점을 둔 유닉스-계열 쉘입니다. Fish는 고도로 구성-가능한 것이 아니라 기본적으로 기능-풍부하도록 설계되었습니다. Fish는 관리자의 재량에 따라 POSIX 쉘 표준을 준수하지 않기 때문에 이국적인 쉘로 고려됩니다.

Introduction

데비안에서 기본 쉘은 Bash (Unix shell)이고, 많은 배포판에서 기본 쉘로 배쉬를 사용합니다.

2025년 기준, 최근 몇 년 내에 기본 쉘을 Z shell로 바꾼 몇 개의 배포판이 있습니다. 배쉬에 비해 Z shell은 여러 플럭인을 통해 충분히 사용자 친화적입니다.

Fish는 설치와 함께 내장된 기능에 의해, 별도의 설정을 하지 않더라도, 충분히 사용자 친화적입니다.

아마도, 배쉬를 사용하다가 처음으로 다른 쉘을 생각 중이라면, Z shell보다는 fish 쉘이 적합할 수 있습니다.

더구나, abbr은 alias와 다르게, 종류별로 무지 많이 만들게 되고, 상당히 효율적입니다.

한편, 이전에 명령-줄에서 사용해 온 Bash (Unix shell) 스크립트는 fish에서 해석이 되지 않기 때문에, sh -c '스크립트'로 실행하거나, fish 명령어를 사용해서 새로 만들어야 합니다.

Useful keyboard shortcuts

긴 명령어를 입력했지만, 잘못 입력했을 때, 전체를 지우는 등의 몇 가지 유용한 단축키는 기억해 둘 필요가 있습니다:

  • 현재 명령-줄의 시작으로 이동: Ctrl+a
  • 현재 명령 힌트 자동완성 : Ctrl+e 또는
  • 현재 명령 힌트 자동완성의 이동 : ↑  and  ↓
  • 명령-줄 비우기: Ctrl+u
  • 명령-줄 비우고, 화면도 비우기 : Ctrl+l

Installation

데비안 자정소에서 설치할 수 있습니다:

  • sudo nala install fish

Configurations

쉘을 fish 바꿉니다:

  • chsh -s $(which fish)

기본 설정 파일을 만듭니다:

  • mkdir -p $HOME/.config/fish
  • touch $HOME/.config/fish/config.fish

Starship (software) 프롬프트로 바꿉니다:

  • vi $HOME/.config/fish/config.fish
starship init fish | source

재시작합니다.

Install plugin manager

플럭인 관리기는 fisher를 설치합니다:

설치합니다:

그런-다음 플럭인을 몇 개 설치합니다: 여기를 참조하십시오:

  • fisher install jethrokuan/z (다른 쉘을 고려해서, zxoide를 고려할 수 있습니다)
  • fisher install patrickf1/fzf.fish
  • fisher install franciscolourenco/done
  • fisher install jorgebucaran/autopair.fish
  • fisher install nickeb96/puffer-fish
  • fisher install paldepind/projectdo

Troubleshootings

GPG won't work with fish

다음을 실행하거나, config 파일에 넣거나 함수로 만들어서 해결할 수 있습니다:

  • set -x GPG_TTY (tty)

Features

Fish는 명령 역사와 현재 디렉토리를 기반으로 사용자가 입력할 때 증분 제안을 표시합니다. 이것은 Bash의 Ctrl+R 역사 검색과 유사하게 작동하지만, 항상 켜져 있어, 명령을 입력하는 동안 사용자에게 지속적인 피드백을 제공합니다. Fish에는 (와일드카드 및 중괄호 확장을 갖는) 파일 경로 확장, 환경 변, 및 명령-지정 완성 기능을 지원과 함께 기능-풍부한 탭 완성 기능도 포함되어 있습니다. 설명을 갖는 옵션을 포함한 명령-지정 완성은 명령의 매뉴얼 페이지에서 어느 정도 생성될 수 있지만, 소프트웨어에 포함되거나 쉘의 사용자에 의해 작성될 수도 있습니다.

Fish의 제작자는 구문보다 명령으로 새로운 기능을 추가하는 것을 선호했습니다. 이것은 내장 기능을 통해 옵션과 도움말 텍스트를 갖는 명령을 검색할 수 있으므로 기능을 더 쉽게 검색하도록 만듭니다. 함수에는 사람이 읽을 수 있는 설명도 포함될 수 있습니다. 특수 도움말(help) 명령은 사용자의 웹 브라우저에 있는 모든 fish 문서로의 접근을 제공합니다.

Syntax

구문은 POSIX 호환 쉘 (예를 들어 Bash)과 비슷하지만, 여러 가지 방법으로 벗어납니다:

# Variable assignment
#
# Set the variable 'foo' to the value 'bar'. 
# Fish doesn't use the = operator, which is inherently whitespace sensitive. 
# The 'set' command extends to work with arrays, scoping, etc.

> set foo bar
> echo $foo
bar
 
# Command substitution
#
# Assign the output of the command 'pwd' into the variable 'wd'. 
# Fish doesn't use backticks (``), which can't be nested and may be confused with single quotes (' '). 

> set wd (pwd)
> set wd $(pwd) # since version 3.4
> echo $wd
~

# Array variables. 'A' becomes an array with 5 values:
> set A 3 5 7 9 12
# Array slicing. 'B' becomes the first two elements of 'A':
> set B $A[1 2]
> echo $B
3 5
# You can index with other arrays and even command 
# substitution output:
> echo $A[(seq 3)]
3 5 7
# Erase the third and fifth elements of 'A'
> set --erase A[$B]
> echo $A
3 5 9

# for-loop, convert jpegs to pngs
> for i in *.jpg
      convert $i (basename $i .jpg).png
  end

# fish supports multi-line history and editing.
# Semicolons work like newlines:
> for i in *.jpg; convert $i (basename $i .jpg).png; end



# while-loop, read lines /etc/passwd and output the fifth 
# colon-separated field from the file. This should be
# the user description.
> while read line
      set arr (echo $line|tr : \n)
      echo $arr[5]
  end < /etc/passwd

# String replacement (replacing all i by I)
> string replace -a "i" "I" "Wikipedia"
WIkIpedIa

No implicit subshell

파이프라인, 함수, 및 루프와 같은 일부 언어 구성은 다른 언어로 소위 서브-쉘을 사용하여 구현되어 왔습니다. 서브-쉘은 작업을 수행하기 위해 몇 가지 명령을 실행하고, 그런-다음 부모 쉘로 다시 나가는 하위 프로그램입니다. 이 구현 세부 사항은 전형적으로 변수 할당과 같은 서브 쉘에서 이루어진 임의의 상태 변경이 주요 쉘로 전파되지 않는 부작용이 있습니다. Fish는 언어 특징에 대한 서브-쉘을 만들지 않습니다; 모든 내장은 부모 쉘 내에서 발생합니다.

# This will not work in many other shells, since the 'read' builtin
# will run in its own subshell. In Bash, the right side of the pipe
# can't have any side effects. In ksh, the below command works, but
# the left side can't have any side effects. In fish and zsh, both
# sides can have side effects.
> cat *.txt | read line

Variable assignment example

이 Bash 예제는 보이는 것을 수행하지 않습니다: 루프 본체는 서브-쉘이기 때문에, $found에 대한 업데이트는 지속적이지 않습니다.

found=''
cat /etc/fstab | while read dev mnt rest; do
  if test "$mnt" = "/"; then
    found="$dev"
  fi
done

해결 방법:

found=''
while read dev mnt rest; do
  if test "$mnt" = "/"; then
    found="$dev"
  fi
done < /etc/fstab

Fish 예제:

set found ''
cat /etc/fstab | while read dev mnt rest
  if test "$mnt" = "/"
    set found $dev
  end
end

Universal variables

Fish는 범용 변수로 알려진 기능을 가지고 있으며, 이는 사용자에게 모든 사용자의 실행 중인 fish 쉘에 걸쳐 변수에 값을 영구적으로 할당하도록 허용합니다. 변수 값은 로그 아웃 및 재부팅에서 기억되고, 업데이트는 모든 실행 중인 쉘로 즉시 전파됩니다.

# This will make emacs the default text editor. The '--universal' (or '-U') tells fish to
# make this a universal variable.
> set --universal EDITOR emacs

# This command will make the current working directory part of the fish
# prompt turn blue on all running fish instances.
> set --universal fish_color_cwd blue

Other features