csh - C 셸
C 셸(csh)은 1978년 버클리 캘리포니아 대학의 Bill Joy가 개발한 Unix 셸입니다. 대화형 사용을 위해 더 C 언어와 유사한 문법을 제공하도록 설계되었으며, 명령 히스토리, 별칭, 작업 제어 등 후속 셸의 표준이 된 많은 기능을 도입했습니다. csh와 그 향상된 버전인 tcsh는 주로 대화형 세션에 사용되며 스크립팅에는 덜 사용되지만, 특정 Unix 환경에서 여전히 중요하며 일부 사용자가 선호하는 고유한 기능을 제공합니다. 레거시 시스템이나 특정 Unix 배포판에서 csh를 이해하는 것은 시스템 관리자와 사용자에게 중요합니다.
설치 및 설정
C 셸 변형
# Check which csh variant is available
which csh
/bin/csh
which tcsh
/usr/bin/tcsh
# Check shell version
echo $version
# tcsh 6.22.04 (Astron) 2021-04-26 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
# Check if running csh or tcsh
echo $shell
/bin/tcsh
C 셸 설치
# Ubuntu/Debian
sudo apt update && sudo apt install csh tcsh
# CentOS/RHEL/Fedora
sudo dnf install tcsh
# macOS (tcsh is usually pre-installed)
# For csh specifically:
brew install tcsh
# Arch Linux
sudo pacman -S tcsh
# FreeBSD (usually pre-installed)
pkg install tcsh
# Check installation
csh --version
tcsh --version
csh/tcsh를 기본 셸로 설정
# Check current shell
echo $SHELL
# Add csh to available shells
echo /bin/csh|sudo tee -a /etc/shells
echo /bin/tcsh|sudo tee -a /etc/shells
# Set tcsh as default shell (recommended over csh)
chsh -s /bin/tcsh
# Verify change (restart terminal)
echo $SHELL
/bin/tcsh
기본 구성 파일
# Configuration files for csh/tcsh
~/.cshrc # Main configuration file
~/.tcshrc # tcsh-specific configuration
~/.login # Login shell configuration
~/.logout # Logout script
# Create basic .tcshrc
cat > ~/.tcshrc ``<< 'EOF'
# tcsh configuration
# Set environment variables
setenv EDITOR vi
setenv PAGER less
setenv LANG en_US.UTF-8
# Set path
set path = (/usr/local/bin /usr/bin /bin $path)
# Aliases
alias ll 'ls -l'
alias la 'ls -la'
alias h 'history'
alias .. 'cd ..'
# Prompt
set prompt = '%n@%m:%c$ '
# History
set history = 1000
set savehist = 1000
# Completion
set autolist
set complete = enhance
# Other options
set noclobber
set notify
EOF
# Source configuration
source ~/.tcshrc
C 셸 문법과 변수
변수 할당 및 사용
# Simple variable assignment
set name = "John Doe"
set age = 30
set path_var = "/home/user"
# Using variables
echo $name
echo "Hello, $name"
echo 'Literal: $name' # Single quotes prevent expansion
# Array variables
set fruits = (apple banana orange)
set numbers = (1 2 3 4 5)
# Accessing array elements
echo $fruits[1] # First element (1-indexed)
echo $fruits[2] # Second element
echo $fruits[$#fruits] # Last element
echo $fruits[*] # All elements
echo $#fruits # Number of elements
# Environment variables
setenv PATH "/usr/local/bin:$PATH"
setenv EDITOR vi
setenv HOME /home/user
# Unset variables
unset name
unsetenv PATH # Dangerous!
# Special variables
echo $0 # Shell name
echo $ # Process ID
echo $? # Exit status of last command
echo $#argv # Number of arguments
echo $argv[*] # All arguments
문자열 연산
# String concatenation
set first = "Hello"
set second = "World"
set combined = "$first, $second!"
echo $combined # Hello, World!
# String length (tcsh)
set string = "Hello, World!"
echo $%string # Length: 13
# Substring operations (limited in csh)
set filename = "document.txt"
set basename = $filename:r # Remove extension: document
set extension = $filename:e # Get extension: txt
set dirname = $filename:h # Get directory (if path)
set tail = $filename:t # Get filename (if path)
# Case conversion (tcsh)
set upper = $string:u # Uppercase
set lower = $string:l # Lowercase
명령 치환
# Command substitution using backticks
set current_date = `date`
set file_count = `ls|wc -l`
set user_home = `eval echo ~$USER`
# Using command substitution in expressions
echo "Today is `date +%A`"
set files = (`ls *.txt`)
# Nested command substitution
set day_of_week = `date +%A`
echo "Today is $day_of_week, `date +%B` `date +%d`"
제어 구조
조건문
# if-then-else
if ($age >`` 18) then
echo "Adult"
else if ($age == 18) then
echo "Just turned adult"
else
echo "Minor"
endif
# String comparisons
if ("$name" == "John") then
echo "Hello John"
endif
if ("$name" != "John") then
echo "Not John"
endif
# File tests
if (-f "file.txt") then
echo "File exists"
endif
if (-d "directory") then
echo "Directory exists"
endif
if (-r "file.txt") then
echo "File is readable"
endif
if (-w "file.txt") then
echo "File is writable"
endif
if (-x "script.sh") then
echo "File is executable"
endif
# Logical operators
if ($age > 18 && $age ``< 65) then
echo "Working age"
endif
if ($status == 0||$force == "true") then
echo "Proceeding"
endif
if (! -f "file.txt") then
echo "File does not exist"
endif
Switch 문
# switch statement
switch ($variable)
case pattern1:
echo "Matched pattern1"
breaksw
case pattern2:
case pattern3:
echo "Matched pattern2 or pattern3"
breaksw
default:
echo "No pattern matched"
breaksw
endsw
# Switch with file extensions
switch ($filename)
case *.txt:
echo "Text file"
breaksw
case *.jpg:
case *.png:
case *.gif:
echo "Image file"
breaksw
case *.sh:
echo "Shell script"
breaksw
default:
echo "Unknown file type"
breaksw
endsw
반복문
# foreach loop
foreach item (apple banana orange)
echo "Fruit: $item"
end
# foreach with array variable
set files = (*.txt)
foreach file ($files)
echo "Processing: $file"
end
# foreach with command substitution
foreach user (`cat users.txt`)
echo "User: $user"
end
# while loop
set counter = 1
while ($counter <= 10)
echo "Counter: $counter"
@ counter++
end
# while loop with file reading
set line = ""
while (1)
set line = $<
if ($line == "") break
echo "Line: $line"
end
# Nested loops
foreach dir (/usr /opt /var)
foreach file ($dir/*)
if (-f $file) then
echo "File: $file"
endif
end
end
산술 연산
@ 명령을 사용한 산술 연산
# Basic arithmetic
@ result = 5 + 3 # 8
@ result = 10 - 4 # 6
@ result = 6 * 7 # 42
@ result = 20 / 4 # 5
@ result = 17 % 5 # 2 (modulo)
# Arithmetic with variables
set num1 = 10
set num2 = 5
@ sum = $num1 + $num2 # 15
@ product = $num1 * $num2 # 50
# Increment and decrement
set counter = 0
@ counter++ # Increment
@ counter-- # Decrement
@ counter += 5 # Add and assign
@ counter -= 3 # Subtract and assign
# Complex expressions
@ result = ($num1 + $num2) * 2
@ result = $num1 ** 2 # Exponentiation (tcsh)
# Comparison operations
@ is_greater = ($num1 >`` $num2) # Returns 1 if true, 0 if false
if ($is_greater) then
echo "num1 is greater than num2"
endif
외부 산술 도구
# Using expr for complex calculations
set result = `expr 5 + 3`
set result = `expr $num1 \* $num2` # Note: * must be escaped
# Using bc for floating point
set result = `echo "scale=2; 10/3"|bc`
set result = `echo "scale=4; sqrt(16)"|bc -l`
# Using awk for calculations
set result = `awk "BEGIN \\{print 10/3\\}"`
별칭과 히스토리
별칭 관리
# Simple aliases
alias ll 'ls -l'
alias la 'ls -la'
alias h 'history'
alias .. 'cd ..'
alias ... 'cd ../..'
# Aliases with arguments
alias rm 'rm -i' # Interactive removal
alias cp 'cp -i' # Interactive copy
alias mv 'mv -i' # Interactive move
# Complex aliases
alias lsd 'ls -l|grep "^d"' # List only directories
alias psg 'ps aux|grep' # Process search
# Conditional aliases
if (-f /usr/bin/vim) then
alias vi vim
endif
# List aliases
alias # Show all aliases
alias ll # Show specific alias
# Remove aliases
unalias ll
unalias * # Remove all aliases
히스토리 관리
# History configuration
set history = 1000 # Number of commands to remember
set savehist = 1000 # Number of commands to save to file
# History commands
history # Show all history
history 10 # Show last 10 commands
history -r # Read history from file
history -w # Write history to file
# History expansion
!! # Previous command
!n # Command number n
!string # Last command starting with string
!?string # Last command containing string
^old^new # Replace old with new in previous command
# History modifiers
!:0 # Command name only
!:1 # First argument
!:$ # Last argument
!:* # All arguments
!:1-3 # Arguments 1 through 3
# Examples
echo !$ # Echo last argument of previous command
cp file.txt !$.bak # Copy file with .bak extension
작업 제어 및 프로세스 관리
작업 제어
# Background jobs
command & # Run command in background
jobs # List active jobs
fg %1 # Bring job 1 to foreground
bg %1 # Send job 1 to background
kill %1 # Kill job 1
# Job control signals
# Ctrl+C: Interrupt (SIGINT)
# Ctrl+Z: Suspend (SIGTSTP)
# Ctrl+\: Quit (SIGQUIT)
# Process management
ps # Show current processes
ps aux # Show all processes
kill PID # Terminate process
kill -9 PID # Force kill process
killall process_name # Kill all processes by name
# Nohup equivalent
nohup command & # Run command immune to hangups
프로세스 정보
# Process variables
echo $ # Current shell PID
echo $! # PID of last background job
# Process status
echo $? # Exit status of last command
echo $status # Same as $? in csh
# Wait for processes
wait # Wait for all background jobs
wait %1 # Wait for specific job
입력/출력 및 리다이렉션
기본 I/O 리다이렉션
# Output redirection
command > file.txt # Redirect stdout to file
command >> file.txt # Append stdout to file
command >& file.txt # Redirect both stdout and stderr
command >>& file.txt # Append both stdout and stderr
# Input redirection
command < input.txt # Read input from file
sort < unsorted.txt > sorted.txt
# Pipes
ls -l|grep "txt" # Pipe output to grep
ps aux|grep "process"|wc -l # Count matching processes
# Here documents (limited support)
cat << EOF
This is a here document
Variables like $HOME are expanded
EOF
고급 I/O 기능
# Noclobber option
set noclobber # Prevent overwriting files
command >! file.txt # Force overwrite with noclobber set
# Tee equivalent
command|tee file.txt # Write to file and stdout
# Error redirection
command >& /dev/null # Redirect both stdout and stderr to null
(command > output.txt) >& error.log # Separate stdout and stderr
내장 명령 및 기능
필수 내장 명령```bash
echo command
echo “Simple message” echo -n “No newline” # tcsh only
printf (tcsh only)
printf “%s: %d\n” “Count” 42 printf ”%-10s %5d\n” “Name” 123
set and setenv
set var = value # Local variable setenv VAR value # Environment variable
which and where
which command # Show command location where command # Show all command locations (tcsh)
Directory operations
cd directory # Change directory pushd directory # Push directory onto stack popd # Pop directory from stack dirs # Show directory stack
File operations
ls -l # List files cp source dest # Copy files mv old new # Move/rename files rm file # Remove files mkdir directory # Create directory rmdir directory # Remove empty directory
```bash
# Command completion
set complete = enhance # Enhanced completion
set autolist # Automatically list completions
# Spelling correction
set correct = cmd # Correct commands
set correct = complete # Correct completions
set correct = all # Correct everything
# File completion
set filec # Enable filename completion
# Auto-logout
set autologout = 60 # Auto-logout after 60 minutes
# Watch for logins
set watch = (any any) # Watch for any user login
set who = "%n has %a %l from %M at %t." # Login message format
```## 구성 및 사용자 정의
### 프롬프트 사용자 정의
```bash
# Simple prompts
set prompt = '%n@%m:%c$ ' # user@host:dir$
set prompt = '% ' # Simple %
set prompt = '\! % ' # History number %
# Prompt escape sequences
# %n - Username
# %m - Hostname
# %c - Current directory (basename)
# %C - Current directory (full path)
# %/ - Current directory (full path)
# %~ - Current directory (with ~ substitution)
# %t - Time (12-hour)
# %T - Time (24-hour)
# %p - Time (AM/PM)
# %d - Day of week
# %D - Date
# %w - Month
# %W - Year
# %! - History number
# %# - # if root, % otherwise
# Advanced prompt with colors (tcsh)
set prompt = '%\\\\{\033[1;32m%\\\\}%n@%m%\\\\{\033[0m%\\\\}:%\\\\{\033[1;34m%\\\\}%c%\\\\{\033[0m%\\\\}$ '
# Multi-line prompt
set prompt = '%n@%m:%c\
$ '
# Conditional prompt
if ($uid == 0) then
set prompt = 'root@%m:%c# '
else
set prompt = '%n@%m:%c$ '
endif
```### 환경 구성
```bash
# Path management
set path = (/usr/local/bin /usr/bin /bin)
set path = ($path /opt/bin) # Append to path
# Environment variables
setenv EDITOR vi
setenv PAGER less
setenv BROWSER firefox
setenv LANG en_US.UTF-8
# Platform-specific configuration
switch (`uname`)
case Linux:
setenv LS_COLORS 'di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30'
breaksw
case Darwin:
setenv LSCOLORS ExFxCxDxBxegedabagacad
breaksw
endsw
# Conditional environment
if (-d "$HOME/.local/bin") then
set path = ($HOME/.local/bin $path)
endif
if ($?DISPLAY) then
setenv BROWSER firefox
else
setenv BROWSER lynx
endif
```### 셸 옵션
```bash
# Important shell options
set noclobber # Prevent file overwriting
set notify # Report job status immediately
set noglob # Disable filename expansion
set ignoreeof # Don't exit on Ctrl+D
# tcsh-specific options
set autolist # List completions automatically
set complete = enhance # Enhanced completion
set correct = cmd # Correct commands
set filec # Filename completion
set histdup = erase # Remove duplicate history entries
set listjobs = long # Long format for job listing
set rmstar # Ask before rm *
```## 스크립팅 고려사항
### 스크립트 구조
```bash
#!/bin/csh -f
# Script description
# Note: -f flag prevents reading .cshrc
# Variable declarations
set script_name = $0:t
set script_dir = $0:h
set version = "1.0"
# Function equivalent (using goto/label)
goto main
usage:
echo "Usage: $script_name [options] [arguments]"
echo "Options:"
echo " -h Show this help"
echo " -v Show version"
exit 0
version:
echo "$script_name version $version"
exit 0
error:
echo "Error: $error_msg"
exit 1
main:
# Parse arguments
while ($#argv > 0)
switch ($argv[1])
case -h:
goto usage
case -v:
goto version
case -*:
set error_msg = "Unknown option: $argv[1]"
goto error
default:
break
endsw
shift argv
end
# Main script logic
echo "Script execution completed"
exit 0
```### csh 스크립트의 모범 사례
```bash
# Use tcsh instead of csh for scripts
#!/bin/tcsh -f
# Always use -f flag to avoid .cshrc interference
#!/bin/csh -f
# Error handling
set error_exit = 0
if (! -f "required_file.txt") then
echo "Error: Required file not found"
set error_exit = 1
endif
if ($error_exit) exit 1
# Input validation
if ($#argv == 0) then
echo "Error: No arguments provided"
exit 1
endif
# Safe variable usage
if ($?variable) then
echo "Variable is set: $variable"
else
echo "Variable is not set"
endif
# Avoid complex scripting in csh
# Use sh/bash for complex scripts
# Use csh/tcsh primarily for interactive use
```## 제한 사항 및 대안
### 알려진 제한 사항
```bash
# csh scripting limitations:
# 1. No functions (use goto/labels instead)
# 2. Limited error handling
# 3. No local variables in "functions"
# 4. Inconsistent syntax
# 5. Poor signal handling
# Example of workaround for function-like behavior
goto main
# "Function" using goto/label
process_file:
set file = $1
if (-f $file) then
echo "Processing $file"
# Process file here
else
echo "File $file not found"
endif
goto return_point
main:
set return_point = main_continue
set argv[1] = "test.txt"
goto process_file
main_continue:
echo "Back in main"
exit 0
```### csh/tcsh 사용 시기
```bash
# Good for:
# - Interactive shell use
# - Simple automation tasks
# - Users familiar with C-like syntax
# - Legacy system compatibility
# Not recommended for:
# - Complex scripting (use bash/sh instead)
# - Portable scripts
# - Production automation
# - Error-critical applications
# Migration example from csh to bash
# csh version:
# if ($status == 0) then
# echo "Success"
# endif
# bash equivalent:
# if [ $? -eq 0 ]; then
# echo "Success"
# fi
```### 상호 운용성
```bash
# Running bash scripts from csh
bash script.sh
# Converting csh variables for bash
setenv BASH_VAR $csh_var
bash -c 'echo $BASH_VAR'
# Calling csh from bash
csh -c 'echo $csh_variable'
# Mixed environment
# Use bash for scripting, csh for interactive
exec bash script.sh # Execute bash script
exec tcsh # Return to tcsh
```C 셸과 그 향상된 버전인 tcsh는 Unix 셸 진화의 중요한 장을 나타내며, 이후 셸에서 표준이 된 많은 기능을 도입했습니다. csh는 다양한 제한 사항과 일관성 부족으로 인해 복잡한 스크립팅에는 권장되지 않지만, 특히 C와 유사한 구문과 특정 기능을 선호하는 사용자를 위해 대화형 사용에는 여전히 가치가 있습니다. csh를 이해하는 것은 레거시 시스템에서 마주치는 시스템 관리자와 명령줄 상호 작용에 대한 고유한 접근 방식을 appreciate하는 사용자에게 중요합니다. 그러나 현대의 셸 스크립팅 요구 사항의 경우, bash와 같은 POSIX 호환 셸 또는 zsh와 같은 더 고급 셸이 일반적으로 선호됩니다.