Bạn đang vật lộn với lỗi khó chịu 'syntax error near unexpected token `then`' khi viết script trên Linux? Đừng lo lắng! Lỗi này khá phổ biến, đặc biệt khi làm việc với các câu lệnh điều kiện if...then...fi
phức tạp hoặc khi thực thi các lệnh từ xa qua SSH. Bài viết này sẽ cung cấp cho bạn cái nhìn sâu sắc về nguyên nhân gây ra lỗi này và các giải pháp hiệu quả để khắc phục nó, giúp bạn viết script mượt mà và tránh những "cơn đau đầu" không đáng có.
Lỗi 'syntax error near unexpected token `then`' thường xuất hiện khi trình thông dịch Bash gặp phải từ khóa then
ở một vị trí không hợp lệ trong cấu trúc câu lệnh. Dưới đây là một số nguyên nhân phổ biến:
if
trước then
: Đây là lỗi cơ bản nhất. Đảm bảo rằng mọi then
đều đi kèm với một if
tương ứng.if
: Nếu điều kiện trong if
bị sai cú pháp, trình thông dịch có thể không nhận diện được và báo lỗi ở then
.-eq
, -ne
, -gt
, -lt
, =
, ==
phải được sử dụng đúng ngữ cảnh (số hay chuỗi) và đúng cú pháp.eval
không cẩn thận: Lệnh eval
có thể gây ra các lỗi cú pháp khó lường nếu không được sử dụng một cách thận trọng.Hãy xem xét ví dụ sau, thường gặp khi thực thi lệnh từ xa qua SSH:
for vm in {20..30} ; do ssh -q -o "StrictHostKeyChecking no" 192.168.210.${vm} "hostname; echo $password | su - root -c \"\ if $(whoami | grep -q root);then echo Good; else echo Bad;fi \"" ; done
Trong ví dụ này, lỗi 'syntax error near unexpected token `then`' xảy ra do việc quoting không chính xác. Cụ thể, phần $(whoami | grep -q root)
được thực thi trên máy cục bộ (SSH client) chứ không phải trên máy chủ từ xa (SSH server). Ngoài ra, việc sử dụng biến $password
trực tiếp trong lệnh có thể gây lộ mật khẩu.
Cách khắc phục:
id -u
để kiểm tra quyền root thay vì whoami | grep -q root
.Dưới đây là phiên bản đã sửa đổi (vẫn dùng mật khẩu, nhưng an toàn hơn):
for ip in 192.168.210.{20..30}; do
LC_PASS=$password ssh -o SendEnv=LC_PASS \
-o StrictHostKeyChecking=no -q "$ip" '
uname -n # standard equivalent of hostname
printf "%s\n" "$LC_PASS" |
su - root -c '\''
if [ "$(id -u)" -eq 0 ]; then
echo Good
else
echo Bad
fi'\''
'
done
eval
không đúng cáchĐôi khi, việc sử dụng eval
có thể dẫn đến lỗi 'syntax error near unexpected token `then`' do câu lệnh được tạo ra không hợp lệ. Ví dụ:
STARTUP="if [ -f entrypoint.sh ]; then {{COMMAND}}; fi;"
EVAL_SCRIPT=`eval echo $(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')`
${EVAL_SCRIPT}
Lỗi xảy ra vì eval
được sử dụng quá nhiều lần, dẫn đến việc câu lệnh bị phân tách và thực thi không đúng. Cụ thể, eval echo if [ -f entrypoint.sh ]
sẽ in ra if [ -f entrypoint.sh ]
, sau đó then {{COMMAND}}; fi;
sẽ bị coi là một lệnh riêng biệt và gây ra lỗi.
Cách khắc phục:
eval
. Nếu có thể, hãy tìm cách khác để tạo và thực thi câu lệnh.eval
, hãy đảm bảo rằng câu lệnh được tạo ra hoàn chỉnh và hợp lệ trước khi thực thi.Phiên bản đã sửa đổi:
STARTUP="if [ -f entrypoint.sh ]; then {{COMMAND}}; fi;"
EVAL_SCRIPT=$(echo ${STARTUP} | sed -e 's/{{/${/g' -e 's/}}/}/g')
eval ${EVAL_SCRIPT}
if...then...fi
để đảm bảo không có lỗi chính tả hoặc thiếu sót.set -x
để in ra các lệnh được thực thi.Hy vọng bài viết này đã giúp bạn hiểu rõ hơn về lỗi 'syntax error near unexpected token `then`' và cách khắc phục nó. Chúc bạn viết script thành công!
Bài viết liên quan